home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-07 | 175.5 KB | 6,168 lines |
- diff -u -r --new-file last-version/docs/smb.conf.5 samba-1.9.14p3/docs/smb.conf.5
- --- last-version/docs/smb.conf.5 Sun Sep 17 10:28:23 1995
- +++ samba-1.9.14p3/docs/smb.conf.5 Sun Nov 5 11:35:38 1995
- @@ -1510,7 +1510,7 @@
-
- The string can contain the macros %o and %n which are substituted for
- the old and new passwords respectively. It can aso contain the
- -standard macros \n \r \t and \s to give line-feed, carriage-return,
- +standard macros \\n \\r \\t and \\s to give line-feed, carriage-return,
- tab and space.
-
- The string can also contain a * which matches any sequence of
- @@ -1524,11 +1524,11 @@
- then no string is expected.
-
- .B Example:
- - passwd chat = "*Enter OLD password*" %o\n "*Enter NEW password*" %n\n \
- - "*Reenter NEW password*" %n\n "*Password changed*"
- + passwd chat = "*Enter OLD password*" %o\\n "*Enter NEW password*" %n\\n \\
- + "*Reenter NEW password*" %n\\n "*Password changed*"
-
- .B Default:
- - passwd chat = *old*password* %o\n *new*password* %n\n *new*password* %n\n *changed*
- + passwd chat = *old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*
-
- .SS passwd program (G)
- The name of a program that can be used to set user passwords.
- diff -u -r --new-file last-version/source/Makefile samba-1.9.14p3/source/Makefile
- --- last-version/source/Makefile Thu Sep 21 20:24:34 1995
- +++ samba-1.9.14p3/source/Makefile Tue Nov 7 22:58:21 1995
- @@ -422,7 +422,8 @@
- CFLAGS = $(CFLAGS5) $(DCE_FLAGS) $(DES_FLAGS) $(PASSWD_FLAGS) $(VTP_FLAGS)
- LIBS = $(LIBS1) $(LIBSM) $(DCE_LIBS) $(DES_LIB)
-
- -PROGS = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd
- +PROGS1 = smbd smbclient nmbd testparm testprns smbrun smbstatus smbpasswd
- +PROGS = $(PROGS1) nmbd2
- SCRIPTS = smbtar
-
- all : CHECK $(PROGS)
- @@ -436,8 +437,10 @@
- INCLUDES2 = pcap.h trans2.h reply.h
- INCLUDES = $(INCLUDES1) $(INCLUDES2)
-
- -UTILOBJ = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
- -PARAMOBJ = $(UTILOBJ) loadparm.o params.o pcap.o access.o username.o ufc.o smbpass.o
- +UTILOBJ1 = util.o system.o charset.o kanji.o fault.o smbencrypt.o charcnv.o
- +UTILOBJ = $(UTILOBJ1) md4.o
- +PARAMOBJ1 = $(UTILOBJ) loadparm.o params.o pcap.o access.o username.o
- +PARAMOBJ = $(PARAMOBJ1) ufc.o smbpass.o
- SMBDOBJ1 = $(PARAMOBJ) trans2.o message.o dir.o printing.o locking.o
- SMBDOBJ2 = ipc.o reply.o mangle.o chgpasswd.o password.o
- SMBDOBJ = $(SMBDOBJ1) $(SMBDOBJ2) $(VTP_OBJ)
- @@ -457,9 +460,13 @@
- @echo Linking smbrun
- @$(CC) $(CFLAGS) -o smbrun smbrun.o $(LIBS)
-
- -nmbd: nameserv.o $(UTILOBJ)
- +nmbd: nameserv.o $(UTILOBJ)
- @echo Linking nmbd
- @$(CC) $(CFLAGS) -o nmbd nameserv.o $(UTILOBJ) $(LIBS)
- +
- +nmbd2: nameserv2.o nmblib.o $(UTILOBJ)
- + @echo Linking nmbd2
- + @$(CC) $(CFLAGS) -o nmbd2 nameserv2.o nmblib.o $(UTILOBJ) $(LIBS)
-
- smbclient: client.o clitar.o $(UTILOBJ)
- @echo Linking smbclient
- diff -u -r --new-file last-version/source/change-log samba-1.9.14p3/source/change-log
- --- last-version/source/change-log Sat Nov 4 23:21:02 1995
- +++ samba-1.9.14p3/source/change-log Tue Nov 7 22:59:06 1995
- @@ -1617,9 +1617,18 @@
- - made rename and unlink look at share locks on file
- - clitar memory leak fix from jjm@jjm.com
- - added -p option to smbstatus to list smbd processes
- + - added rename to the client
- - released p2
- + - fixed SMBmv for case where the destination exists
- + - man page patch from michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
- + - once again redid the time handling, but finally explained what
- + is going on, this is written up in TIME.txt. The "kludge-GMT" used
- + by NT is a bastard and led to a lot of the confusion
- + - kanji patch from fujita@ainix.isac.co.jp (Takashi Fujita)
- + - is08859-1 patches from eauth@mail.cso.co.at
- + - starting rewriting nmbd, new nmbd is nmbd2, old one still around
- + for time being
-
- -
- ==========
- todo:
-
- @@ -1653,6 +1662,10 @@
- document cnvchar stuff
-
- allow smbd to serve user and group lists to win95
- +
- +document homes behaviour with WinDD
- +
- +apparently WfWg doesn't like the password server stuff in 1.9.14. Why?
-
- UNRESOLVED PROBLEMS
- ===================
- diff -u -r --new-file last-version/source/client.c samba-1.9.14p3/source/client.c
- --- last-version/source/client.c Sat Nov 4 21:31:10 1995
- +++ samba-1.9.14p3/source/client.c Tue Nov 7 13:59:55 1995
- @@ -444,12 +444,12 @@
- ****************************************************************************/
- static void display_finfo(file_info *finfo)
- {
- - time_t t = finfo->mtime - DSTDiff(finfo->mtime);
- + time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
- DEBUG(0,(" %-30s%7.7s%10d %s",
- CNV_LANG(finfo->name),
- attrib_string(finfo->mode),
- finfo->size,
- - asctime(LocalTime(&t,0))));
- + asctime(LocalTime(&t,GMT_TO_LOCAL))));
- }
-
- /****************************************************************************
- @@ -492,7 +492,8 @@
- {
- finfo->mode = CVAL(p,21);
-
- - finfo->ctime = make_unix_date(p+22,True);
- + /* this date is converted to GMT by make_unix_date */
- + finfo->ctime = make_unix_date(p+22);
- finfo->mtime = finfo->atime = finfo->ctime;
- finfo->size = IVAL(p,26);
- strcpy(finfo->name,p+30);
- @@ -516,9 +517,10 @@
- case 1: /* OS/2 understands this */
- if (finfo)
- {
- - finfo->ctime = make_unix_date2(p+4,True);
- - finfo->atime = make_unix_date2(p+8,True);
- - finfo->mtime = make_unix_date2(p+12,True);
- + /* these dates are converted to GMT by make_unix_date */
- + finfo->ctime = make_unix_date2(p+4);
- + finfo->atime = make_unix_date2(p+8);
- + finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- strcpy(finfo->name,p+27);
- @@ -528,9 +530,10 @@
- case 2: /* this is what OS/2 uses mostly */
- if (finfo)
- {
- - finfo->ctime = make_unix_date2(p+4,True);
- - finfo->atime = make_unix_date2(p+8,True);
- - finfo->mtime = make_unix_date2(p+12,True);
- + /* these dates are converted to GMT by make_unix_date */
- + finfo->ctime = make_unix_date2(p+4);
- + finfo->atime = make_unix_date2(p+8);
- + finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- strcpy(finfo->name,p+31);
- @@ -541,9 +544,10 @@
- case 3:
- if (finfo)
- {
- - finfo->ctime = make_unix_date2(p+8,True);
- - finfo->atime = make_unix_date2(p+12,True);
- - finfo->mtime = make_unix_date2(p+16,True);
- + /* these dates are probably like the other ones */
- + finfo->ctime = make_unix_date2(p+8);
- + finfo->atime = make_unix_date2(p+12);
- + finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- strcpy(finfo->name,p+33);
- @@ -553,9 +557,10 @@
- case 4:
- if (finfo)
- {
- - finfo->ctime = make_unix_date2(p+8,True);
- - finfo->atime = make_unix_date2(p+12,True);
- - finfo->mtime = make_unix_date2(p+16,True);
- + /* these dates are probably like the other ones */
- + finfo->ctime = make_unix_date2(p+8);
- + finfo->atime = make_unix_date2(p+12);
- + finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- strcpy(finfo->name,p+37);
- @@ -565,17 +570,24 @@
- case 260: /* NT uses this, but also accepts 2 */
- if (finfo)
- {
- - extern int serverzone;
- int ret = SVAL(p,0);
- int namelen;
- p += 4; /* next entry offset */
- p += 4; /* fileindex */
- +
- + /* these dates appear to arrive in a weird way. It seems to
- + be localtime plus the serverzone given in the initial
- + connect. This is GMT when DST is not in effect and one
- + hour from GMT otherwise. Can this really be right??
- +
- + I suppose this could be called kludge-GMT. Is is the GMT
- + you get by using the current DST setting on a different
- + localtime. It will be cheap to calculate, I suppose, as
- + no DST tables will be needed */
- +
- finfo->ctime = interpret_long_date(p); p += 8;
- finfo->atime = interpret_long_date(p); p += 8;
- finfo->mtime = interpret_long_date(p); p += 8; p += 8;
- - finfo->mtime += DSTDiff(finfo->mtime) - serverzone;
- - finfo->ctime += DSTDiff(finfo->ctime) - serverzone;
- - finfo->atime += DSTDiff(finfo->atime) - serverzone;
- finfo->size = IVAL(p,0); p += 8;
- p += 8; /* alloc size */
- finfo->mode = CVAL(p,0); p += 4;
- @@ -1161,12 +1173,15 @@
- }
-
- strcpy(finfo.name,rname);
- +
- if (!finfo1)
- {
- finfo.mode = SVAL(inbuf,smb_vwv3);
- - finfo.mtime = IVAL(inbuf,smb_vwv4);
- - finfo.size = IVAL(inbuf,smb_vwv6);
- + /* these times arrive as LOCAL time, using the DST offset
- + corresponding to that time, we convert them to GMT */
- + finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
- finfo.atime = finfo.ctime = finfo.mtime;
- + finfo.size = IVAL(inbuf,smb_vwv6);
- }
-
- DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
- @@ -1536,7 +1551,8 @@
- if (lowercase)
- strlower(finfo->name);
-
- - if (!directory_exist(finfo->name) && sys_mkdir(finfo->name,0777) != 0)
- + if (!directory_exist(finfo->name,NULL) &&
- + sys_mkdir(finfo->name,0777) != 0)
- {
- DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
- strcpy(cur_dir,saved_curdir);
- @@ -1834,25 +1850,18 @@
- return;
- }
-
- - if (close_time != 0 && close_time != -1)
- - close_time -= TimeDiff(close_time);
- -
- bzero(outbuf,smb_size);
- set_message(outbuf,3,2 + strlen(rname),True);
-
- if (finfo->mtime == 0 || finfo->mtime == -1)
- - {
- - time_t t = time(NULL);
- - finfo->mtime = finfo->atime = finfo->ctime =
- - t + GMT_TO_LOCAL*TimeDiff(t);
- - }
- -
- + finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
- +
- CVAL(outbuf,smb_com) = SMBcreate;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,finfo->mode);
- - SIVAL(outbuf,smb_vwv1,finfo->mtime);
- + put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- @@ -1927,12 +1936,8 @@
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- - SSVAL(outbuf,smb_vwv0,fnum);
- - SIVAL(outbuf,smb_vwv1,close_time);
- -
- - DEBUG(3,("Setting date to %s (0x%X)",
- - asctime(LocalTime(&finfo->mtime,LOCAL_TO_GMT)),
- - finfo->mtime));
- + SSVAL(outbuf,smb_vwv0,fnum);
- + put_dos_date3(outbuf,smb_vwv1,close_time);
-
- send_smb(outbuf);
- receive_smb(inbuf,CLIENT_TIMEOUT);
- @@ -2000,8 +2005,14 @@
-
- dos_clean_name(rname);
-
- - /* let the remote side decide the date */
- - finfo.mtime = -1;
- + {
- + struct stat st;
- + if (!file_exist(lname,&st)) {
- + DEBUG(0,("%s does not exist\n"));
- + return;
- + }
- + finfo.mtime = st.st_mtime;
- + }
-
- do_put(rname,lname,&finfo);
- }
- @@ -2054,6 +2065,7 @@
-
- while (next_token(NULL,p,NULL))
- {
- + struct stat st;
- pstring cmd;
- pstring tmpname;
- FILE *f;
- @@ -2078,7 +2090,7 @@
- again1:
-
- /* check if it's a directory */
- - if (directory_exist(lname))
- + if (directory_exist(lname,&st))
- {
- if (!recurse) continue;
- sprintf(quest,"Put directory %s? ",lname);
- @@ -2115,8 +2127,8 @@
- /* null size so do_put knows to ignore it */
- finfo.size = -1;
-
- - /* let the remote side decide the date */
- - finfo.mtime = -1;
- + /* set the date on the file */
- + finfo.mtime = st.st_mtime;
-
- do_put(rname,lname,&finfo);
- }
- @@ -2584,8 +2596,9 @@
- ok = next_token(NULL,buf,NULL);
- if (ok && (sys_stat(buf,&sbuf) == 0))
- {
- - newer_than = sbuf.st_mtime + GMT_TO_LOCAL*TimeDiff(sbuf.st_mtime);
- - DEBUG(1,("Getting files newer than %s",asctime(LocalTime(&newer_than,0))));
- + newer_than = sbuf.st_mtime;
- + DEBUG(1,("Getting files newer than %s",
- + asctime(LocalTime(&newer_than,GMT_TO_LOCAL))));
- }
- else
- newer_than = 0;
- @@ -2895,8 +2908,9 @@
- sec_mode = SVAL(inbuf,smb_vwv1);
- max_xmit = SVAL(inbuf,smb_vwv2);
- sesskey = IVAL(inbuf,smb_vwv6);
- - servertime = make_unix_date(inbuf+smb_vwv8,False);
- serverzone = SVALS(inbuf,smb_vwv10)*60;
- + /* this time is converted to GMT by make_unix_date */
- + servertime = make_unix_date(inbuf+smb_vwv8);
- if (Protocol >= PROTOCOL_COREPLUS) {
- readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
- writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
- @@ -2913,8 +2927,8 @@
- max_xmit = IVAL(inbuf,smb_vwv3+1);
- sesskey = IVAL(inbuf,smb_vwv7+1);
- serverzone = SVALS(inbuf,smb_vwv15+1)*60;
- + /* this time arrives in real GMT */
- servertime = interpret_long_date(inbuf+smb_vwv11+1);
- - servertime -= serverzone;
- crypt_len = CVAL(inbuf,smb_vwv16+1);
- memcpy(cryptkey,smb_buf(inbuf),8);
- if (IVAL(inbuf,smb_vwv9+1) & 1)
- @@ -2937,7 +2951,7 @@
- static BOOL done_time = False;
- if (!done_time) {
- DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
- - asctime(LocalTime(&servertime,0)),
- + asctime(LocalTime(&servertime,GMT_TO_LOCAL)),
- -(double)(serverzone/3600.0)));
- done_time = True;
- }
- @@ -3805,12 +3819,13 @@
- pstring query_host;
- BOOL message = False;
-
- - charset_initialise();
- -
- *query_host = 0;
-
- DEBUGLEVEL = 2;
- dbf = stdout;
- +
- + TimeInit();
- + charset_initialise();
-
- pid = getpid();
- uid = getuid();
- diff -u -r --new-file last-version/source/clitar.c samba-1.9.14p3/source/clitar.c
- --- last-version/source/clitar.c Sat Nov 4 23:05:01 1995
- +++ samba-1.9.14p3/source/clitar.c Mon Nov 6 16:17:43 1995
- @@ -441,7 +441,7 @@
- {
- finfo.mode = SVAL(inbuf,smb_vwv3);
- finfo.size = IVAL(inbuf,smb_vwv4);
- - finfo.mtime = IVAL(inbuf,smb_vwv6);
- + finfo.mtime = make_unix_date3(inbuf+smb_vwv6);
- finfo.atime = finfo.ctime = finfo.mtime;
- }
-
- @@ -856,7 +856,6 @@
- */
- finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
- finfo->atime = time(NULL);
- - finfo->atime += GMT_TO_LOCAL*TimeDiff(finfo->atime);
- finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
-
- return True;
- @@ -923,7 +922,7 @@
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,finfo.mode);
- - SIVAL(outbuf,smb_vwv1,finfo.mtime);
- + put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- @@ -996,10 +995,10 @@
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- - SIVAL(outbuf,smb_vwv1,finfo.mtime-TimeDiff(finfo.mtime));
- + put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-
- DEBUG(3,("Setting date to %s (0x%X)",
- - asctime(LocalTime(&finfo.mtime,LOCAL_TO_GMT)),
- + asctime(LocalTime(&finfo.mtime,GMT_TO_LOCAL)),
- finfo.mtime));
-
- send_smb(outbuf);
- diff -u -r --new-file last-version/source/dir.c samba-1.9.14p3/source/dir.c
- --- last-version/source/dir.c Thu Sep 21 20:58:46 1995
- +++ samba-1.9.14p3/source/dir.c Tue Nov 7 12:46:56 1995
- @@ -436,7 +436,7 @@
- strcpy(filename,dname);
-
- if ((strcmp(filename,mask) == 0) ||
- - (name_convert(filename,dname,True,SNUM(cnum)) &&
- + (name_map_mangle(filename,True,SNUM(cnum)) &&
- mask_match(filename,mask,False,False)))
- {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- diff -u -r --new-file last-version/source/includes.h samba-1.9.14p3/source/includes.h
- --- last-version/source/includes.h Sat Nov 4 21:51:34 1995
- +++ samba-1.9.14p3/source/includes.h Tue Nov 7 12:49:21 1995
- @@ -84,7 +84,6 @@
- #define PASSWORD_LENGTH 16
- #endif
-
- -
- /* here is the general includes section - with some ifdefs generated
- by the previous section
- */
- @@ -755,6 +754,13 @@
- end of the platform specific sections
- ********************************************************************/
-
- +#ifndef MAXINT
- +#define MAXINT ((((unsigned)1)<<(sizeof(int)*8-1))-1)
- +#endif
- +
- +#ifndef __STDC__
- +#define const
- +#endif
-
- /* Now for some other grungy stuff */
- #ifdef NO_GETSPNAM
- @@ -958,6 +964,10 @@
- #define F_WRLCK 0
- #define F_UNLCK 0
- #endif /* HAVE_FCNTL_LOCK == 0 */
- +
- +#ifdef NOSTRCASECMP
- +#define strcasecmp(s1,s2) StrCaseCmp(s1,s2)
- +#endif
-
- #ifndef strcpy
- #define strcpy(dest,src) StrCpy(dest,src)
- diff -u -r --new-file last-version/source/ipc.c samba-1.9.14p3/source/ipc.c
- --- last-version/source/ipc.c Sat Nov 4 18:58:24 1995
- +++ samba-1.9.14p3/source/ipc.c Mon Nov 6 16:54:58 1995
- @@ -458,6 +458,11 @@
- struct pack_desc* desc,
- print_queue_struct* queue, int n)
- {
- + time_t t = queue->time;
- +
- + /* the client expects localtime */
- + t += GMT_TO_LOCAL*TimeDiff(t);
- +
- PACKI(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */
- if (uLevel == 1) {
- PACKS(desc,"B21",queue->user); /* szUserName */
- @@ -709,8 +714,7 @@
- /****************************************************************************
- get info about a share
- ****************************************************************************/
- -
- -static int check_share_info(int uLevel, const char* id)
- +static int check_share_info(int uLevel, char* id)
- {
- switch( uLevel ) {
- case 0:
- @@ -944,11 +948,13 @@
- {
- struct tm *t;
- time_t unixdate = time(NULL);
- - unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
- +
- + put_dos_date3(p,0,unixdate); /* this is the time that is looked at by NT
- + in a "net time" operation */
-
- - t = LocalTime(&unixdate,0);
- + /* the client expects to get localtime, not GMT */
- + t = LocalTime(&unixdate,GMT_TO_LOCAL);
-
- - SIVAL(p,0,unixdate);
- SIVAL(p,4,0); /* msecs ? */
- CVAL(p,8) = t->tm_hour;
- CVAL(p,9) = t->tm_min;
- @@ -995,7 +1001,7 @@
-
- DEBUG(3,("Set password for <%s>\n",user));
-
- - if (!password_ok(user,pass1,strlen(pass1),NULL) ||
- + if (!password_ok(user,pass1,strlen(pass1),NULL,False) ||
- !chgpasswd(user,pass1,pass2))
- SSVAL(*rparam,0,NERR_badpass);
-
- @@ -1128,7 +1134,7 @@
- or <WWsTP> <WB21BB16B10zWWzDDz>
- ****************************************************************************/
- static int check_printjob_info(struct pack_desc* desc,
- - int uLevel, const char* id)
- + int uLevel, char* id)
- {
- desc->subformat = NULL;
- switch( uLevel ) {
- @@ -1766,7 +1772,7 @@
- }
-
- static int check_printdest_info(struct pack_desc* desc,
- - int uLevel, const char* id)
- + int uLevel, char* id)
- {
- desc->subformat = NULL;
- switch( uLevel ) {
- diff -u -r --new-file last-version/source/kanji.h samba-1.9.14p3/source/kanji.h
- --- last-version/source/kanji.h Thu Sep 21 20:49:48 1995
- +++ samba-1.9.14p3/source/kanji.h Tue Nov 7 11:03:48 1995
- @@ -27,9 +27,6 @@
- #define _KANJI_H_
-
- #ifdef KANJI
- -#ifndef REPLACE_RENAME
- -#define REPLACE_RENAME
- -#endif
-
- /* FOR SHIFT JIS CODE */
- #define is_shift_jis(c) \
- diff -u -r --new-file last-version/source/local.h samba-1.9.14p3/source/local.h
- --- last-version/source/local.h Sun Oct 22 13:51:03 1995
- +++ samba-1.9.14p3/source/local.h Sun Nov 5 12:37:52 1995
- @@ -140,4 +140,9 @@
-
- #define SMB_ALIGNMENT 1
-
- +
- +/* shall we support browse requests via a FIFO to nmbd? */
- +#define ENABLE_FIFO 1
- +
- +
- #endif
- diff -u -r --new-file last-version/source/mangle.c samba-1.9.14p3/source/mangle.c
- --- last-version/source/mangle.c Fri Sep 15 20:34:00 1995
- +++ samba-1.9.14p3/source/mangle.c Tue Nov 7 12:33:19 1995
- @@ -533,11 +533,8 @@
- /****************************************************************************
- convert a filename to DOS format. return True if successful.
- ****************************************************************************/
- -BOOL name_convert(char *OutName,char *InName,BOOL need83,int snum)
- +BOOL name_map_mangle(char *OutName,BOOL need83,int snum)
- {
- - /* initially just copy it */
- - strcpy(OutName,unix2dos_format(InName,False));
- -
- /* apply any name mappings */
- {
- char *map = lp_mangled_map(snum);
- diff -u -r --new-file last-version/source/md4.c samba-1.9.14p3/source/md4.c
- --- last-version/source/md4.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/md4.c Tue Nov 7 12:44:48 1995
- @@ -0,0 +1,299 @@
- +#ifdef SMB_PASSWD
- +/*
- + This code is from rfc1186.
- +*/
- +
- + /*
- + ** ********************************************************************
- + ** md4.c -- Implementation of MD4 Message Digest Algorithm **
- + ** Updated: 2/16/90 by Ronald L. Rivest **
- + ** (C) 1990 RSA Data Security, Inc. **
- + ** ********************************************************************
- + */
- +
- + /*
- + ** To use MD4:
- + ** -- Include md4.h in your program
- + ** -- Declare an MDstruct MD to hold the state of the digest
- + ** computation.
- + ** -- Initialize MD using MDbegin(&MD)
- + ** -- For each full block (64 bytes) X you wish to process, call
- + ** MDupdate(&MD,X,512)
- + ** (512 is the number of bits in a full block.)
- + ** -- For the last block (less than 64 bytes) you wish to process,
- + ** MDupdate(&MD,X,n)
- + ** where n is the number of bits in the partial block. A partial
- + ** block terminates the computation, so every MD computation
- + ** should terminate by processing a partial block, even if it
- + ** has n = 0.
- + ** -- The message digest is available in MD.buffer[0] ...
- + ** MD.buffer[3]. (Least-significant byte of each word
- + ** should be output first.)
- + ** -- You can print out the digest using MDprint(&MD)
- + */
- +
- + /* Implementation notes:
- + ** This implementation assumes that ints are 32-bit quantities.
- + ** If the machine stores the least-significant byte of an int in the
- + ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
- + ** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
- + ** should be set to FALSE. Note that on machines with LOWBYTEFIRST
- + ** FALSE the routine MDupdate modifies has a side-effect on its input
- + ** array (the order of bytes in each word are reversed). If this is
- + ** undesired a call to MDreverse(X) can reverse the bytes of X back
- + ** into order after each call to MDupdate.
- + */
- +
- +#define TRUE 1
- +#define FALSE 0
- +
- + /* Compile-time includes
- + */
- +
- +#include <stdio.h>
- +#include "md4.h"
- +
- +#define uchar unsigned char
- +#define int16 unsigned short
- +#define uint32 unsigned int
- +
- +#include "byteorder.h"
- +
- + /* Compile-time declarations of MD4 "magic constants".
- + */
- +#define I0 0x67452301 /* Initial values for MD buffer */
- +#define I1 0xefcdab89
- +#define I2 0x98badcfe
- +#define I3 0x10325476
- +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
- +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
- + /* C2 and C3 are from Knuth, The Art of Programming, Volume 2
- + ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
- + ** Table 2, page 660.
- + */
- +
- +#define fs1 3 /* round 1 shift amounts */
- +#define fs2 7
- +#define fs3 11
- +#define fs4 19
- +#define gs1 3 /* round 2 shift amounts */
- +#define gs2 5
- +#define gs3 9
- +#define gs4 13
- +#define hs1 3 /* round 3 shift amounts */
- +#define hs2 9
- +#define hs3 11
- +#define hs4 15
- +
- + /* Compile-time macro declarations for MD4.
- + ** Note: The "rot" operator uses the variable "tmp".
- + ** It assumes tmp is declared as unsigned int, so that the >>
- + ** operator will shift in zeros rather than extending the sign bit.
- + */
- +#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
- +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
- +#define h(X,Y,Z) (X^Y^Z)
- +#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
- +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
- +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
- +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
- +
- + /* MDprint(MDp)
- + ** Print message digest buffer MDp as 32 hexadecimal digits.
- + ** Order is from low-order byte of buffer[0] to high-order byte of
- + ** buffer[3].
- + ** Each byte is printed with high-order hexadecimal digit first.
- + ** This is a user-callable routine.
- + */
- + void
- + MDprint(MDp)
- + MDptr MDp;
- + { int i,j;
- + for (i=0;i<4;i++)
- + for (j=0;j<32;j=j+8)
- + printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
- + }
- +
- + /* MDbegin(MDp)
- + ** Initialize message digest buffer MDp.
- + ** This is a user-callable routine.
- + */
- + void
- + MDbegin(MDp)
- + MDptr MDp;
- + { int i;
- + MDp->buffer[0] = I0;
- + MDp->buffer[1] = I1;
- + MDp->buffer[2] = I2;
- + MDp->buffer[3] = I3;
- + for (i=0;i<8;i++) MDp->count[i] = 0;
- + MDp->done = 0;
- + }
- +
- + /* MDreverse(X)
- + ** Reverse the byte-ordering of every int in X.
- + ** Assumes X is an array of 16 ints.
- + ** The macro revx reverses the byte-ordering of the next word of X.
- + */
- + void MDreverse(X)
- + unsigned int *X;
- + { register unsigned int t;
- + register unsigned int i;
- +
- + for(i = 0; i < 16; i++) {
- + t = X[i];
- + SIVAL(X,i*4,t);
- + }
- + }
- +
- + /* MDblock(MDp,X)
- + ** Update message digest buffer MDp->buffer using 16-word data block X.
- + ** Assumes all 16 words of X are full of data.
- + ** Does not update MDp->count.
- + ** This routine is not user-callable.
- + */
- + static void
- + MDblock(MDp,X)
- + MDptr MDp;
- + unsigned int *X;
- + {
- + register unsigned int tmp, A, B, C, D;
- + MDreverse(X);
- + A = MDp->buffer[0];
- + B = MDp->buffer[1];
- + C = MDp->buffer[2];
- + D = MDp->buffer[3];
- + /* Update the message digest buffer */
- + ff(A , B , C , D , 0 , fs1); /* Round 1 */
- + ff(D , A , B , C , 1 , fs2);
- + ff(C , D , A , B , 2 , fs3);
- + ff(B , C , D , A , 3 , fs4);
- + ff(A , B , C , D , 4 , fs1);
- + ff(D , A , B , C , 5 , fs2);
- + ff(C , D , A , B , 6 , fs3);
- + ff(B , C , D , A , 7 , fs4);
- + ff(A , B , C , D , 8 , fs1);
- + ff(D , A , B , C , 9 , fs2);
- + ff(C , D , A , B , 10 , fs3);
- + ff(B , C , D , A , 11 , fs4);
- + ff(A , B , C , D , 12 , fs1);
- + ff(D , A , B , C , 13 , fs2);
- + ff(C , D , A , B , 14 , fs3);
- + ff(B , C , D , A , 15 , fs4);
- + gg(A , B , C , D , 0 , gs1); /* Round 2 */
- + gg(D , A , B , C , 4 , gs2);
- + gg(C , D , A , B , 8 , gs3);
- + gg(B , C , D , A , 12 , gs4);
- + gg(A , B , C , D , 1 , gs1);
- + gg(D , A , B , C , 5 , gs2);
- + gg(C , D , A , B , 9 , gs3);
- + gg(B , C , D , A , 13 , gs4);
- + gg(A , B , C , D , 2 , gs1);
- + gg(D , A , B , C , 6 , gs2);
- + gg(C , D , A , B , 10 , gs3);
- + gg(B , C , D , A , 14 , gs4);
- + gg(A , B , C , D , 3 , gs1);
- + gg(D , A , B , C , 7 , gs2);
- + gg(C , D , A , B , 11 , gs3);
- + gg(B , C , D , A , 15 , gs4);
- + hh(A , B , C , D , 0 , hs1); /* Round 3 */
- + hh(D , A , B , C , 8 , hs2);
- + hh(C , D , A , B , 4 , hs3);
- + hh(B , C , D , A , 12 , hs4);
- + hh(A , B , C , D , 2 , hs1);
- + hh(D , A , B , C , 10 , hs2);
- + hh(C , D , A , B , 6 , hs3);
- + hh(B , C , D , A , 14 , hs4);
- + hh(A , B , C , D , 1 , hs1);
- + hh(D , A , B , C , 9 , hs2);
- + hh(C , D , A , B , 5 , hs3);
- + hh(B , C , D , A , 13 , hs4);
- + hh(A , B , C , D , 3 , hs1);
- + hh(D , A , B , C , 11 , hs2);
- + hh(C , D , A , B , 7 , hs3);
- + hh(B , C , D , A , 15 , hs4);
- + MDp->buffer[0] += A;
- + MDp->buffer[1] += B;
- + MDp->buffer[2] += C;
- + MDp->buffer[3] += D;
- + }
- +
- + /* MDupdate(MDp,X,count)
- + ** Input: MDp -- an MDptr
- + ** X -- a pointer to an array of unsigned characters.
- + ** count -- the number of bits of X to use.
- + ** (if not a multiple of 8, uses high bits of last byte.)
- + ** Update MDp using the number of bits of X given by count.
- + ** This is the basic input routine for an MD4 user.
- + ** The routine completes the MD computation when count < 512, so
- + ** every MD computation should end with one call to MDupdate with a
- + ** count less than 512. A call with count 0 will be ignored if the
- + ** MD has already been terminated (done != 0), so an extra call with
- + ** count 0 can be given as a "courtesy close" to force termination
- + ** if desired.
- + */
- + void
- + MDupdate(MDp,X,count)
- + MDptr MDp;
- + unsigned char *X;
- + unsigned int count;
- + { unsigned int i, tmp, bit, byte, mask;
- + unsigned char XX[64];
- + unsigned char *p;
- + /* return with no error if this is a courtesy close with count
- + ** zero and MDp->done is true.
- + */
- + if (count == 0 && MDp->done) return;
- + /* check to see if MD is already done and report error */
- + if (MDp->done)
- + { printf("\nError: MDupdate MD already done."); return; }
- + /* Add count to MDp->count */
- + tmp = count;
- + p = MDp->count;
- + while (tmp)
- + { tmp += *p;
- + *p++ = tmp;
- + tmp = tmp >> 8;
- + }
- + /* Process data */
- + if (count == 512)
- + { /* Full block of data to handle */
- + MDblock(MDp,(unsigned int *)X);
- + }
- + else if (count > 512) /* Check for count too large */
- + { printf("\nError: MDupdate called with illegal count value %d."
- + ,count);
- + return;
- + }
- + else /* partial block -- must be last block so finish up */
- + { /* Find out how many bytes and residual bits there are */
- + byte = count >> 3;
- + bit = count & 7;
- + /* Copy X into XX since we need to modify it */
- + for (i=0;i<=byte;i++) XX[i] = X[i];
- + for (i=byte+1;i<64;i++) XX[i] = 0;
- + /* Add padding '1' bit and low-order zeros in last byte */
- + mask = 1 << (7 - bit);
- + XX[byte] = (XX[byte] | mask) & ~( mask - 1);
- + /* If room for bit count, finish up with this block */
- + if (byte <= 55)
- + { for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
- + MDblock(MDp,(unsigned int *)XX);
- + }
- + else /* need to do two blocks to finish up */
- + { MDblock(MDp,(unsigned int *)XX);
- + for (i=0;i<56;i++) XX[i] = 0;
- + for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
- + MDblock(MDp,(unsigned int *)XX);
- + }
- + /* Set flag saying we're done with MD computation */
- + MDp->done = 1;
- + }
- + }
- +
- + /*
- + ** End of md4.c
- + */
- +#else
- +void md4_dummy() {;}
- +#endif
- diff -u -r --new-file last-version/source/md4.h samba-1.9.14p3/source/md4.h
- --- last-version/source/md4.h Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/md4.h Tue Nov 7 10:50:21 1995
- @@ -0,0 +1,58 @@
- +/*
- + This code is from rfc1186.
- +*/
- +
- + /*
- + ** ********************************************************************
- + ** md4.h -- Header file for implementation of **
- + ** MD4 Message Digest Algorithm **
- + ** Updated: 2/13/90 by Ronald L. Rivest **
- + ** (C) 1990 RSA Data Security, Inc. **
- + ** ********************************************************************
- + */
- +
- + /* MDstruct is the data structure for a message digest computation.
- + */
- + typedef struct {
- + unsigned int buffer[4]; /* Holds 4-word result of MD computation */
- + unsigned char count[8]; /* Number of bits processed so far */
- + unsigned int done; /* Nonzero means MD computation finished */
- + } MDstruct, *MDptr;
- +
- + /* MDbegin(MD)
- +
- +
- +
- + ** Input: MD -- an MDptr
- + ** Initialize the MDstruct prepatory to doing a message digest
- + ** computation.
- + */
- + extern void MDbegin();
- +
- + /* MDupdate(MD,X,count)
- + ** Input: MD -- an MDptr
- + ** X -- a pointer to an array of unsigned characters.
- + ** count -- the number of bits of X to use (an unsigned int).
- + ** Updates MD using the first "count" bits of X.
- + ** The array pointed to by X is not modified.
- + ** If count is not a multiple of 8, MDupdate uses high bits of
- + ** last byte.
- + ** This is the basic input routine for a user.
- + ** The routine terminates the MD computation when count < 512, so
- + ** every MD computation should end with one call to MDupdate with a
- + ** count less than 512. Zero is OK for a count.
- + */
- + extern void MDupdate();
- +
- + /* MDprint(MD)
- + ** Input: MD -- an MDptr
- + ** Prints message digest buffer MD as 32 hexadecimal digits.
- + ** Order is from low-order byte of buffer[0] to high-order byte
- + ** of buffer[3].
- + ** Each byte is printed with high-order hexadecimal digit first.
- + */
- + extern void MDprint();
- +
- + /*
- + ** End of md4.h
- + */
- diff -u -r --new-file last-version/source/mksmbpasswd.sh samba-1.9.14p3/source/mksmbpasswd.sh
- --- last-version/source/mksmbpasswd.sh Tue Jul 11 13:41:45 1995
- +++ samba-1.9.14p3/source/mksmbpasswd.sh Sun Nov 5 15:46:37 1995
- @@ -2,5 +2,5 @@
- awk 'BEGIN {FS=":"
- printf("#\n# SMB password file.\n#\n")
- }
- -{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
- +{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
- '
- diff -u -r --new-file last-version/source/nameserv.c samba-1.9.14p3/source/nameserv.c
- --- last-version/source/nameserv.c Fri Sep 22 17:39:32 1995
- +++ samba-1.9.14p3/source/nameserv.c Tue Nov 7 14:08:34 1995
- @@ -43,7 +43,6 @@
- static int num_good_receives=0;
- static pstring lookup="";
- static int Client138=-1;
- -
- enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
-
- /* this is the structure used for the local netbios name table */
- @@ -493,12 +492,13 @@
- /****************************************************************************
- interpret a node status response
- ****************************************************************************/
- -static void interpret_node_status(char *inbuf,char *master)
- +static void interpret_node_status(char *inbuf, char *master)
- {
- int level = master?3:0;
- char *p = inbuf + 12 + name_len(inbuf+12) + 10;
- int numnames = CVAL(p,0);
- DEBUG(level,("received %d names\n",numnames));
- +
- p += 1;
- while (numnames--)
- {
- @@ -508,6 +508,7 @@
- StrnCpy(qname,p,15);
- type = CVAL(p,15);
- p += 16;
- +
- if (p[0] & 0x80) strcat(flags,"<GROUP> ");
- if (p[0] & 0x60 == 0) strcat(flags,"B ");
- if (p[0] & 0x60 == 1) strcat(flags,"P ");
- @@ -649,8 +650,8 @@
- /****************************************************************************
- do a netbios name query to find someones IP
- ****************************************************************************/
- -static BOOL name_query(char *name,char name_type,BOOL bcast,
- - struct in_addr to_ip,struct in_addr *ip,void (*fn)())
- +static BOOL name_query(char *name, char name_type, BOOL bcast,
- + struct in_addr to_ip, struct in_addr *ip, void (*fn)())
- {
- BOOL found=False;
- pstring inbuf,outbuf;
- @@ -738,7 +739,8 @@
- /****************************************************************************
- do a netbios name status to a host
- ****************************************************************************/
- -static BOOL name_status(char *name,int type,struct in_addr to_ip,void (*fn)(),char *master)
- +static BOOL name_status(char *name,int type,struct in_addr to_ip,void (*fn)(),
- + char *master)
- {
- pstring inbuf,outbuf;
- static uint16 name_trn_id = 0x4262;
- @@ -806,7 +808,7 @@
- if (rcode==0 && ancount==1 && qdcount==0) {
- DEBUG(fn?3:0,("Got a positive node status response from %s\n",
- inet_ntoa(lastip)));
- - interpret_node_status(inbuf,master);
- + interpret_node_status(inbuf, master);
- return(True);
- }
- return(False);
- @@ -1606,7 +1608,6 @@
- first = False;
- }
-
- -
- /****************************************************************************
- process commands from the client
- ****************************************************************************/
- @@ -1678,13 +1679,13 @@
- static BOOL open_sockets(BOOL isdaemon,int port)
- {
- struct hostent *hp;
- -
- +
- /* get host info */
- if ((hp = Get_Hostbyname(myhostname)) == 0)
- {
- DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
- return False;
- - }
- + }
-
- if (isdaemon)
- Client = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
- @@ -1702,8 +1703,10 @@
- set_socket_options(Client138,"SO_BROADCAST");
- set_socket_options(Client,user_socket_options);
-
- +
- + DEBUG(3, ("Socket opened.\n"));
- return True;
- -}
- +};
-
-
- /****************************************************************************
- @@ -1734,7 +1737,8 @@
- Netmask = ip2;
- }
-
- - DEBUG(1,("Using IP %s ",inet_ntoa(myip)));
- + DEBUG(1,("Using IP %s ",inet_ntoa(myip))); /* core dump reported
- + doing this. Why?? XXXXX */
- DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip)));
- DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));
-
- @@ -1797,6 +1801,8 @@
-
- *lookup = *host_file = 0;
-
- + TimeInit();
- +
- charset_initialise();
-
- strcpy(debugf,NMBLOGFILE);
- @@ -1988,6 +1994,9 @@
- DEBUG(2,("%s becoming a daemon\n",timestring()));
- become_daemon();
- }
- +
- +
- + DEBUG(3,("Opening sockets\n"));
-
- if (open_sockets(is_daemon,port))
- {
- diff -u -r --new-file last-version/source/nameserv.h samba-1.9.14p3/source/nameserv.h
- --- last-version/source/nameserv.h Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/nameserv.h Tue Nov 7 22:17:38 1995
- @@ -0,0 +1,130 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios header - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- +*/
- +
- +#define MAX_DGRAM_SIZE 576
- +#define MIN_DGRAM_SIZE 12
- +
- +#define NMB_PORT 137
- +#define DGRAM_PORT 138
- +
- +/* a netbios name structure */
- +struct nmb_name {
- + char name[17];
- + char scope[64];
- + int name_type;
- +};
- +
- +/* a resource record */
- +struct res_rec {
- + struct nmb_name rr_name;
- + int rr_type;
- + int rr_class;
- + int ttl;
- + int rdlength;
- + char rdata[MAX_DGRAM_SIZE];
- +};
- +
- +/* define a nmb packet. */
- +struct nmb_packet
- +{
- + struct {
- + int name_trn_id;
- + int opcode;
- + BOOL response;
- + struct {
- + BOOL bcast;
- + BOOL recursion_available;
- + BOOL recursion_desired;
- + BOOL trunc;
- + BOOL authoritative;
- + } nm_flags;
- + int rcode;
- + int qdcount;
- + int ancount;
- + int nscount;
- + int arcount;
- + } header;
- +
- + struct {
- + struct nmb_name question_name;
- + int question_type;
- + int question_class;
- + } question;
- +
- + struct res_rec *answers;
- + struct res_rec *nsrecs;
- + struct res_rec *additional;
- +};
- +
- +
- +/* a datagram - a simple structure at first, it would be good to parse
- + it properly later */
- +struct dgram_packet {
- + struct {
- + int res;
- + int id;
- + struct in_addr ip;
- + int port;
- + int length;
- + int res2;
- + struct nmb_name source_name;
- + struct nmb_name dest_name;
- + } header;
- + int smbsize;
- + char smb_data[MAX_DGRAM_SIZE];
- +};
- +
- +enum packet_type {NMB_PACKET, DGRAM_PACKET};
- +
- +/* define a structure used to queue packets. this will be a linked
- + list of nmb packets */
- +struct packet_struct
- +{
- + struct packet_struct *next;
- + struct packet_struct *prev;
- + struct in_addr ip;
- + int port;
- + int fd;
- + time_t timestamp;
- + enum packet_type packet_type;
- + union {
- + struct nmb_packet nmb;
- + struct dgram_packet dgram;
- + } packet;
- +};
- +
- +
- +/* this defines a list of network interfaces */
- +struct net_interface {
- + struct net_interface *next;
- + struct in_addr ip;
- + struct in_addr bcast;
- + struct in_addr netmask;
- +};
- +
- +
- +/* prototypes */
- +void free_nmb_packet(struct nmb_packet *nmb);
- +void free_packet(struct packet_struct *packet);
- +struct packet_struct *read_packet(int fd,enum packet_type packet_type);
- +BOOL send_packet(struct packet_struct *p);
- +struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
- diff -u -r --new-file last-version/source/nameserv2.c samba-1.9.14p3/source/nameserv2.c
- --- last-version/source/nameserv2.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/nameserv2.c Tue Nov 7 22:37:02 1995
- @@ -0,0 +1,1980 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- +*/
- +
- +#include "includes.h"
- +#include "nameserv.h"
- +
- +
- +static void queue_packet(struct packet_struct *packet);
- +
- +
- +extern int DEBUGLEVEL;
- +
- +/* the list of network interfaces */
- +struct net_interface *interfaces = NULL;
- +
- +extern pstring debugf;
- +extern int DEBUGLEVEL;
- +
- +extern pstring scope;
- +
- +static int browse_interval = BROWSE_INTERVAL;
- +
- +static BOOL dns_serve = False;
- +static BOOL CanRecurse = True;
- +
- +extern struct in_addr lastip;
- +extern int lastport;
- +extern struct in_addr myip;
- +extern struct in_addr bcast_ip;
- +extern struct in_addr Netmask;
- +extern pstring myhostname;
- +static pstring host_file;
- +static pstring myname="";
- +static pstring lookup="";
- +static int ClientNMB=-1;
- +static int ClientDGRAM=-1;
- +enum name_sources {LMHOSTS, REGISTER, SELF, DNS};
- +
- +/* this is the structure used for the local netbios name table */
- +typedef struct
- +{
- + time_t start_time;
- + int ttl;
- + struct in_addr ip;
- + struct in_addr master_ip;
- + BOOL found_master;
- + BOOL valid;
- + BOOL isgroup;
- + BOOL unicast;
- + char name[100];
- + int type;
- + int count;
- + enum name_sources source;
- +} name_struct;
- +
- +
- +static int num_names=0;
- +static name_struct *names = NULL;
- +
- +#define NAMEVALID(i) names[i].valid
- +#define ISGROUP(i) (names[i].isgroup)
- +
- +void process(void);
- +
- +/* are we running as a daemon ? */
- +static BOOL is_daemon = False;
- +
- +/* machine comment */
- +static pstring comment="";
- +
- +extern pstring user_socket_options;
- +
- +static void add_group_name(char *name);
- +static void add_host_name(char *name,int type,struct in_addr *ip);
- +static void dump_names(void);
- +
- +
- +static BOOL got_bcast = False;
- +static BOOL got_myip = False;
- +static BOOL got_nmask = False;
- +
- +
- +/****************************************************************************
- +catch a sighup
- +****************************************************************************/
- +static int sig_hup()
- +{
- + BlockSignals(True);
- +
- + DEBUG(0,("Got SIGHUP - not implemented\n"));
- + dump_names();
- + if (!is_daemon)
- + exit(1);
- +
- + BlockSignals(False);
- +#ifndef DONT_REINSTALL_SIG
- + signal(SIGHUP,SIGNAL_CAST sig_hup);
- +#endif
- + return(0);
- +}
- +
- +/****************************************************************************
- +catch a sigpipe
- +****************************************************************************/
- +static int sig_pipe()
- +{
- + BlockSignals(True);
- +
- + DEBUG(0,("Got SIGPIPE\n"));
- + if (!is_daemon)
- + exit(1);
- + BlockSignals(False);
- + return(0);
- +}
- +
- +/****************************************************************************
- +possibly continue after a fault
- +****************************************************************************/
- +static void fault_continue(void)
- +{
- + static int errcount=0;
- +
- + errcount++;
- +
- + if (is_daemon && errcount<100)
- + process();
- +
- + exit(1);
- +}
- +
- +/****************************************************************************
- + true if two netbios names are equal
- +****************************************************************************/
- +static BOOL name_equal(char *s1,char *s2,int type1,int type2)
- +{
- + char n1[20],n2[20];
- +
- + if (type1 != type2) return(False);
- +
- + StrnCpy(n1,s1,15);
- + StrnCpy(n2,s2,15);
- +
- + trim_string(n1,NULL," ");
- + trim_string(n2,NULL," ");
- +
- + return(strequal(n1,n2));
- +}
- +
- +/****************************************************************************
- +add a netbios name
- +****************************************************************************/
- +static int add_name(void)
- +{
- + int i;
- +
- + for (i=0;i<num_names;i++)
- + if (!names[i].valid)
- + break;
- +
- + if (i==num_names) {
- + name_struct *n;
- + if (num_names == 0)
- + n = (name_struct *)malloc(sizeof(name_struct));
- + else
- + n = (name_struct *)realloc(names,sizeof(name_struct)*(num_names+1));
- + if (!n) {
- + DEBUG(0,("Can't malloc more names space!\n"));
- + return(-1);
- + }
- + i = num_names;
- + num_names++;
- + names = n;
- + }
- +
- + bzero(&names[i],sizeof(names[i]));
- +
- + return(i);
- +}
- +
- +/****************************************************************************
- +find a name
- +****************************************************************************/
- +static int find_name(char *s,int type,BOOL groups)
- +{
- + int i;
- + time_t t = time(NULL);
- +
- + for (i=0;i<num_names;i++)
- + if (names[i].valid && (groups || !ISGROUP(i)))
- + {
- + if ((names[i].ttl > 0) && (t > (names[i].start_time + names[i].ttl)))
- + names[i].valid = False;
- + else
- + {
- + if (name_equal(s,names[i].name,type,names[i].type)) {
- + return(i);
- + }
- + }
- + }
- + return -1;
- +}
- +
- +
- +/****************************************************************************
- +check names, and change any 0 IPs to myip
- +****************************************************************************/
- +static void check_names(void)
- +{
- + int i;
- + int group_count=0;
- +
- + /* add the magic __SAMBA__ name */
- + add_host_name("__SAMBA__",0x20,&myip);
- + add_host_name("__SAMBA__",0x0,&myip);
- +
- + for (i=0;i<num_names;i++)
- + if (names[i].valid) {
- + if (ISGROUP(i)) group_count++;
- + }
- +
- + if (group_count == 0)
- + add_group_name(WORKGROUP);
- +
- +
- + for (i=0;i<num_names;i++)
- + if (names[i].valid && strequal((char *)inet_ntoa(names[i].ip),"0.0.0.0"))
- + names[i].ip = (ISGROUP(i)?bcast_ip:myip);
- +}
- +
- +
- +/****************************************************************************
- +dump a copy of the name table
- +****************************************************************************/
- +static void dump_names(void)
- +{
- + int i;
- + DEBUG(3,("Dump of local name table\n"));
- + for (i=0;i<num_names;i++)
- + if (names[i].valid) {
- + DEBUG(3,("%s %s %d %s",
- + names[i].name,inet_ntoa(names[i].ip),
- + names[i].ttl,BOOLSTR(names[i].isgroup)));
- + if (names[i].found_master)
- + DEBUG(3,(" %s",inet_ntoa(names[i].master_ip)));
- + DEBUG(3,("\n"));
- + }
- +}
- +
- +
- +/****************************************************************************
- +load a netbios hosts file
- +****************************************************************************/
- +static void load_hosts_file(char *fname)
- +{
- + int i;
- + FILE *f = fopen(fname,"r");
- + pstring line;
- + if (!f)
- + {
- + DEBUG(2,("Not using non-existant lmhosts file %s\n",fname));
- + return;
- + }
- +
- + while (!feof(f))
- + {
- + if (!fgets_slash(line,sizeof(pstring),f)) continue;
- +
- + if (*line == '#') continue;
- +
- + {
- + string ip="",name="",flags="",extra="";
- + unsigned long a;
- + char *ptr;
- + int count = 0;
- + ptr = line;
- + if (next_token(&ptr,ip,NULL)) ++count;
- + if (next_token(&ptr,name,NULL)) ++count;
- + if (next_token(&ptr,flags,NULL)) ++count;
- + if (next_token(&ptr,extra,NULL)) ++count;
- +
- + if (count <= 0) continue;
- +
- + if (count > 0 && count < 2)
- + {
- + DEBUG(0,("Ill formed hosts line [%s]\n",line));
- + continue;
- + }
- +
- + i = add_name();
- + if (i < 0)
- + {
- + fclose(f);
- + return;
- + }
- +
- + a = interpret_addr(ip);
- + putip((char *)&names[i].ip,(char *)&a);
- +
- + names[i].valid = True;
- + names[i].source = LMHOSTS;
- +
- + StrnCpy(names[i].name,name,15);
- + if (strchr(flags,'G') || strchr(flags,'S'))
- + names[i].isgroup = True;
- + if (strchr(flags,'M') && !ISGROUP(i))
- + strcpy(myname,name);
- + if (strchr(flags,'U'))
- + names[i].unicast = True;
- + if (names[i].isgroup)
- + names[i].type = 0xF0; /* hopefully invalid */
- + else
- + names[i].type = 0x20;
- + }
- + }
- +
- + fclose(f);
- +}
- +
- +
- +/****************************************************************************
- +add a netbios group name
- +****************************************************************************/
- +static void add_group_name(char *name)
- +{
- + int i = add_name();
- + if (i < 0)
- + return;
- +
- + bzero((char *)&names[i].ip,sizeof(names[i].ip));
- +
- + strcpy(names[i].name,name);
- + names[i].isgroup = True;
- + names[i].valid = True;
- + names[i].type = 0xF0;
- + names[i].source = SELF;
- +}
- +
- +/****************************************************************************
- +add a host name
- +****************************************************************************/
- +static void add_host_name(char *name,int type,struct in_addr *ip)
- +{
- + int i;
- +
- + if (find_name(name,type,True) >= 0) return;
- +
- + i = add_name();
- + if (i < 0)
- + return;
- +
- + names[i].ip = *ip;
- + strcpy(names[i].name,name);
- + names[i].valid = True;
- + names[i].start_time = time(NULL);
- + names[i].ttl = 0;
- + names[i].type = type;
- + names[i].source = SELF;
- +}
- +
- +/****************************************************************************
- +work out the length of a nmb message
- +****************************************************************************/
- +static int nmb_len(char *buf)
- +{
- +int i;
- +int ret = 12;
- +char *p = buf;
- +int qdcount = RSVAL(buf,4);
- +int ancount = RSVAL(buf,6);
- +int nscount = RSVAL(buf,8);
- +int arcount = RSVAL(buf,10);
- +
- +/* check for insane qdcount values? */
- +if (qdcount > 100 || qdcount < 0)
- + {
- + DEBUG(6,("Invalid qdcount? qdcount=%d\n",qdcount));
- + return(0);
- + }
- +
- +for (i=0;i<qdcount;i++)
- + {
- + p = buf + ret;
- + ret += name_len(p) + 4;
- + }
- +
- +for (i=0;i<(ancount + nscount + arcount);i++)
- + {
- + int rdlength;
- + p = buf + ret;
- + ret += name_len(p) + 8;
- + p = buf + ret;
- + rdlength = RSVAL(p,0);
- + ret += rdlength + 2;
- + }
- +
- +return(ret);
- +}
- +
- +/****************************************************************************
- +receive a name message. timeout is in milliseconds
- +****************************************************************************/
- +static int receive_nmb(char *buffer,int timeout)
- +{
- + int ret = read_max_udp(ClientNMB,buffer,sizeof(pstring),timeout);
- +
- + if (ret < 0)
- + {
- + DEBUG(0,("No bytes from client\n"));
- + if (!is_daemon)
- + {
- + close_sockets();
- + exit(0);
- + }
- + }
- +
- + if (ret <= 1)
- + return 0;
- +
- + log_in(buffer,ret);
- +
- + DEBUG(3,("received packet from (%s) nmb_len=%d len=%d\n",
- + inet_ntoa(lastip),nmb_len(buffer),ret));
- +
- + return(ret);
- +}
- +
- +/****************************************************************************
- +send a name message
- +****************************************************************************/
- +static BOOL send_nmb(char *buf, int len, struct in_addr *ip,int port)
- +{
- + BOOL ret;
- + struct sockaddr_in sock_out;
- +
- + /* set the address and port */
- + bzero((char *)&sock_out,sizeof(sock_out));
- + putip((char *)&sock_out.sin_addr,(char *)ip);
- + sock_out.sin_port = htons( port );
- + sock_out.sin_family = AF_INET;
- +
- + /* log the packet */
- + log_out(buf,len);
- +
- + if (DEBUGLEVEL > 0)
- + DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
- + len,inet_ntoa(*ip)));
- +
- + /* send it */
- + ret = (sendto(ClientNMB,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
- +
- + if (!ret)
- + DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
- +
- + return(ret);
- +}
- +
- +/*******************************************************************
- +check if an IP is on my net
- +********************************************************************/
- +static BOOL is_mynet(struct in_addr ip)
- +{
- + unsigned int net1,net2,nmask,subnet1,subnet2;
- +
- + nmask = *(unsigned int *)&Netmask;
- + net1 = (*(unsigned int *)&myip);
- + subnet1 = net1 & nmask;
- + net2 = (*(unsigned int *)&ip);
- + subnet2 = net2 & nmask;
- +
- + return((net1 != net2) && (subnet1 == subnet2));
- +}
- +
- +/****************************************************************************
- +interpret a node status response
- +****************************************************************************/
- +static void interpret_node_status(char *inbuf, char *master)
- +{
- + int level = master?3:0;
- + char *p = inbuf + 12 + name_len(inbuf+12) + 10;
- + int numnames = CVAL(p,0);
- + DEBUG(level,("received %d names\n",numnames));
- +
- + p += 1;
- + while (numnames--)
- + {
- + char qname[17];
- + int type;
- + fstring flags="";
- + StrnCpy(qname,p,15);
- + type = CVAL(p,15);
- + p += 16;
- +
- + if (p[0] & 0x80) strcat(flags,"<GROUP> ");
- + if (p[0] & 0x60 == 0) strcat(flags,"B ");
- + if (p[0] & 0x60 == 1) strcat(flags,"P ");
- + if (p[0] & 0x60 == 2) strcat(flags,"M ");
- + if (p[0] & 0x60 == 3) strcat(flags,"_ ");
- + if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
- + if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
- + if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
- + if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
- +
- + if (master && type == 0x1d) {
- + StrnCpy(master,qname,15);
- + }
- +
- + DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
- + p+=2;
- + }
- + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n",
- + IVAL(p,20),IVAL(p,24)));
- +}
- +
- +
- +/****************************************************************************
- +show a nmb message
- +****************************************************************************/
- +static void show_nmb(char *inbuf)
- +{
- + int i,l;
- + int name_trn_id = RSVAL(inbuf,0);
- + int opcode = (CVAL(inbuf,2) >> 3) & 0xF;
- + int nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
- + int rcode = CVAL(inbuf,3) & 0xF;
- + int qdcount = RSVAL(inbuf,4);
- + int ancount = RSVAL(inbuf,6);
- + int nscount = RSVAL(inbuf,8);
- + int arcount = RSVAL(inbuf,10);
- + char name[100];
- +
- + if (DEBUGLEVEL < 3) return;
- +
- + DEBUG(3,("\nPACKET INTERPRETATION\n"));
- +
- + if (opcode == 5 && ((nm_flags & ~1) == 0x10) && rcode == 0)
- + DEBUG(3,("NAME REGISTRATION REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 5 && ((nm_flags & ~1) == 0x00) && rcode == 0)
- + DEBUG(3,("NAME OVERWRITE REQUEST AND DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 9 && ((nm_flags & ~1) == 0x00) && rcode == 0)
- + DEBUG(3,("NAME REFRESH REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 8)
- + DEBUG(3,("NAME REFRESH (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 5 && nm_flags == 0x58 && rcode == 0)
- + DEBUG(3,("POSITIVE NAME REGISTRATION RESPONSE\n"));
- +
- + if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode != 7)
- + DEBUG(3,("NEGATIVE NAME REGISTRATION RESPONSE\n"));
- +
- + if (opcode == 5 && nm_flags == 0x50 && rcode == 0)
- + DEBUG(3,("END-NODE CHALLENGE REGISTRATION RESPONSE\n"));
- +
- + if (opcode == 5 && nm_flags == 0x58 && rcode != 0 && rcode == 7)
- + DEBUG(3,("NAME CONFLICT DEMAND\n"));
- +
- + if (opcode == 6 && (nm_flags&~1) == 0x00 && rcode == 0)
- + DEBUG(3,("NAME RELEASE REQUEST & DEMAND (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode == 0)
- + DEBUG(3,("POSITIVE NAME RELEASE RESPONSE\n"));
- +
- + if (opcode == 6 && (nm_flags&~1) == 0x40 && rcode != 0)
- + DEBUG(3,("NEGATIVE NAME RELEASE RESPONSE\n"));
- +
- + if (opcode == 0 && (nm_flags&~1) == 0x10 && rcode == 0)
- + DEBUG(3,("NAME QUERY REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 0 && (nm_flags&~0x28) == 0x50 && rcode == 0)
- + DEBUG(3,("POSITIVE NAME QUERY RESPONSE\n"));
- +
- + if (opcode == 0 && (nm_flags&~0x08) == 0x50 && rcode != 0)
- + DEBUG(3,("NEGATIVE NAME QUERY RESPONSE\n"));
- +
- + if (opcode == 0 && nm_flags == 0x10 && rcode == 0)
- + DEBUG(3,("REDIRECT NAME QUERY RESPONSE\n"));
- +
- + if (opcode == 7 && nm_flags == 0x80 && rcode == 0)
- + DEBUG(3,("WAIT FOR ACKNOWLEDGEMENT RESPONSE\n"));
- +
- + if (opcode == 0 && (nm_flags&~1) == 0x00 && rcode == 0)
- + DEBUG(3,("NODE STATUS REQUEST (%s)\n",nm_flags&1?"Broadcast":"Unicast"));
- +
- + if (opcode == 0 && nm_flags == 0x40 && rcode == 0)
- + {
- + DEBUG(3,("NODE STATUS RESPONSE\n"));
- + interpret_node_status(inbuf,NULL);
- + }
- +
- +
- + DEBUG(3,("name_trn_id=0x%x\nopcode=0x%x\nnm_flags=0x%x\nrcode=0x%x\n",
- + name_trn_id,opcode,nm_flags,rcode));
- + DEBUG(3,("qdcount=%d\nancount=%d\nnscount=%d\narcount=%d\n",
- + qdcount,ancount,nscount,arcount));
- +
- + l = 12;
- + for (i=0;i<qdcount;i++)
- + {
- + int type,class;
- + DEBUG(3,("QUESTION %d\n",i));
- + name_extract(inbuf,l,name);
- + l += name_len(inbuf+l);
- + type = RSVAL(inbuf+l,0);
- + class = RSVAL(inbuf+l,2);
- + l += 4;
- + DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
- + }
- +
- + for (i=0;i<(ancount + nscount + arcount);i++)
- + {
- + int type,class,ttl,rdlength;
- + DEBUG(3,("RESOURCE %d\n",i));
- + name_extract(inbuf,l,name);
- + l += name_len(inbuf + l);
- + type = RSVAL(inbuf+l,0);
- + class = RSVAL(inbuf+l,2);
- + ttl = RIVAL(inbuf+l,4);
- + rdlength = RSVAL(inbuf+l,8);
- + l += 10 + rdlength;
- + DEBUG(3,("\t%s\n\ttype=0x%x\n\tclass=0x%x\n",name,type,class));
- + DEBUG(3,("\tttl=%d\n\trdlength=%d\n",ttl,rdlength));
- + }
- +
- + DEBUG(3,("\n"));
- +
- +}
- +
- +
- +/****************************************************************************
- +do a netbios name status to a host
- +****************************************************************************/
- +static BOOL name_status(char *name,int type,struct in_addr to_ip,char *master)
- +{
- + pstring inbuf,outbuf;
- + static uint16 name_trn_id = 0x4262;
- + char *p;
- + int retries = 2;
- + int retry_time = 5000;
- + struct timeval tval;
- +
- + bzero(inbuf,sizeof(inbuf));
- + bzero(outbuf,sizeof(outbuf));
- +
- + name_trn_id += getpid() % 100;
- + name_trn_id = (name_trn_id % 10000);
- +
- + RSSVAL(outbuf,0,name_trn_id);
- + CVAL(outbuf,2) = 0;
- + CVAL(outbuf,3) = 0x0;
- + RSSVAL(outbuf,4,1);
- + RSSVAL(outbuf,6,0);
- + RSSVAL(outbuf,8,0);
- + RSSVAL(outbuf,10,0);
- + p = outbuf+12;
- + name_mangle(name,p,type);
- + p += name_len(p);
- + RSSVAL(p,0,0x21);
- + RSSVAL(p,2,0x1);
- + p += 4;
- +
- + show_nmb(outbuf);
- +
- + GetTimeOfDay(&tval);
- +
- + if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
- + return False;
- +
- + while (1)
- + {
- + struct timeval tval2;
- + GetTimeOfDay(&tval2);
- + if (TvalDiff(&tval,&tval2) > retry_time) {
- + if (!retries) break;
- + if (!send_nmb(outbuf,nmb_len(outbuf), &to_ip, NMB_PORT))
- + return False;
- + GetTimeOfDay(&tval);
- + retries--;
- + }
- +
- + if (receive_nmb(inbuf,90))
- + {
- + int rec_name_trn_id = RSVAL(inbuf,0);
- + int rcode = CVAL(inbuf,3) & 0xF;
- + int response = (CVAL(inbuf,2)>>7);
- + int qdcount = RSVAL(inbuf,4);
- + int ancount = RSVAL(inbuf,6);
- +
- + show_nmb(inbuf);
- +
- + /* is it a positive response to our request? */
- + if (response && (rec_name_trn_id == name_trn_id)) {
- + if (rcode==0 && ancount==1 && qdcount==0) {
- + interpret_node_status(inbuf, master);
- + return(True);
- + }
- + return(False);
- + }
- + }
- + }
- +
- + DEBUG(0,("No status response (this is not unusual)\n"));
- +
- + return(False);
- +}
- +
- +/****************************************************************************
- +construct a host announcement unicast
- +****************************************************************************/
- +static BOOL send_udp_dgram(char *buf,int len,
- + char *srcname,char *dstname,
- + int src_type,int dest_type,
- + struct in_addr dest_ip)
- +{
- + pstring outbuf;
- + char *p,*p2;
- + static int id=0;
- + char tmp[4];
- + struct sockaddr_in sock_out;
- +
- + bzero(outbuf,sizeof(outbuf));
- + RSSVAL(outbuf,0,0x1102); /* what is this? */
- + RSSVAL(outbuf,2,++id);
- + putip(outbuf+4,(void *)&myip);
- + RSSVAL(outbuf,8,DGRAM_PORT);
- + RSSVAL(outbuf,12,0);
- + p = outbuf + 14;
- + p += name_mangle(srcname,p,src_type);
- + p += name_mangle(dstname,p,dest_type);
- +
- + /* now setup the smb part */
- + p -= 4;
- + memcpy(tmp,p,4);
- + set_message(p,17,17 + len,True);
- + memcpy(p,tmp,4);
- +
- + CVAL(p,smb_com) = SMBtrans;
- + SSVAL(p,smb_vwv1,len);
- + SSVAL(p,smb_vwv11,len);
- + SSVAL(p,smb_vwv12,86);
- + SSVAL(p,smb_vwv13,3);
- + SSVAL(p,smb_vwv14,1);
- + SSVAL(p,smb_vwv15,1);
- + SSVAL(p,smb_vwv16,2);
- + p2 = smb_buf(p);
- + strcpy(p2,"\\MAILSLOT\\BROWSE");
- + p2 = skip_string(p2,1);
- +
- + memcpy(p2,buf,len);
- + p2 += len;
- +
- + len = PTR_DIFF(p2,outbuf);
- + RSSVAL(outbuf,10,len);
- +
- +
- + /* set the address and port */
- + bzero((char *)&sock_out,sizeof(sock_out));
- + putip((char *)&sock_out.sin_addr,(char *)&dest_ip);
- + sock_out.sin_port = htons(DGRAM_PORT);
- + sock_out.sin_family = AF_INET;
- +
- + /* log the packet */
- + log_out(outbuf,len);
- +
- + /* send it */
- + if (sendto(ClientDGRAM,outbuf,len,0,
- + (struct sockaddr *)&sock_out,sizeof(sock_out)) < 0) {
- + DEBUG(3,("Sendto failed errno=%d (%s)\n",errno,strerror(errno)));
- + return(False);
- + }
- +
- + return(True);
- +}
- +
- +/****************************************************************************
- +construct a host announcement unicast
- +****************************************************************************/
- +static void announce_host(int i,char *my_name,char *Comment)
- +{
- + static int announce_interval = 1;
- + char *group = names[i].name;
- + struct in_addr dest_ip = names[i].ip;
- + pstring outbuf;
- + char *p;
- +
- + names[i].count++;
- +
- + if ((names[i].count % announce_interval) != 0) return;
- +
- + if (announce_interval < 2) announce_interval++;
- +
- + DEBUG(2,("Sending host announcement to %s for group %s\n",
- + inet_ntoa(dest_ip),group));
- +
- + if (!*Comment) Comment = "NoComment";
- + if (!*my_name) my_name = "NoName";
- + if (!*group) group = "NoGroup";
- +
- + if (strlen(Comment) > 47) Comment[47] = 0;
- +
- + bzero(outbuf,sizeof(outbuf));
- + p = outbuf;
- + CVAL(p,0) = 1; /* host announce */
- + SSVAL(p,1,0x6006); /* update count?? */
- + CVAL(p,3) = 0xEA; /* res1 */
- + SSVAL(p,4,announce_interval);
- + p += 6;
- + StrnCpy(p,my_name,16);
- + strupper(p);
- + p += 16;
- + CVAL(p,0) = 1; /* major version (was 1) */
- + CVAL(p,1) = 0x33; /* minor version (was 51) */
- + SIVAL(p,2,0xB03); /* server and w'station + unix + printq + domain member*/
- + SSVAL(p,6,0x30B); /* election version */
- + SSVAL(p,8,0xAA55); /* browse constant */
- + p += 10;
- + strcpy(p,Comment);
- + p += strlen(p)+1;
- +
- + send_udp_dgram(outbuf,PTR_DIFF(p,outbuf),my_name,group,0,0x1d,dest_ip);
- +}
- +
- +
- +
- +/****************************************************************************
- +send a name registration packet
- +****************************************************************************/
- +static void send_registration(char *name,int name_type,struct in_addr dest_ip,struct in_addr ip,BOOL refresh,int ttl)
- +{
- + char *p;
- + static int t = 0x176;
- + pstring outbuf;
- + bzero(outbuf,sizeof(outbuf));
- + /* send a registration request */
- + RSSVAL(outbuf,0,t++);
- + if (refresh)
- + CVAL(outbuf,2) = (0<<7) | (9<<3) | 0;
- + else
- + CVAL(outbuf,2) = (0<<7) | (5<<3) | 1;
- +
- + CVAL(outbuf,3) = (1<<4);
- + RSSVAL(outbuf,4,1);
- + RSSVAL(outbuf,6,0);
- + RSSVAL(outbuf,8,0);
- + RSSVAL(outbuf,10,1);
- + p = outbuf+12;
- + name_mangle(name,p,name_type);
- + p += name_len(p);
- + RSSVAL(p,0,0x20);
- + RSSVAL(p,2,0x1);
- + p += 4;
- + RSSVAL(p,0,12);
- + CVAL(p,0) = CVAL(p,0) | 0xC0;
- + p += 2;
- + RSSVAL(p,0,0x20);
- + RSSVAL(p,2,0x1);
- + p += 4;
- + RSIVAL(p,0,ttl);
- +
- + RSSVAL(p,4,6);
- + RSSVAL(p,6,0);
- + p += 8;
- + putip(p,&ip);
- + p += 4;
- +
- + DEBUG(2,("Sending a name registration request\n"));
- + if (DEBUGLEVEL > 2)
- + show_nmb(outbuf);
- +
- + send_nmb(outbuf,PTR_DIFF(p,outbuf),&dest_ip,NMB_PORT);
- +}
- +
- +/*******************************************************************
- +find a master browser
- +********************************************************************/
- +BOOL find_master(char *name1,struct in_addr ip,struct in_addr *ipout)
- +{
- + int type = 0x1d;
- + fstring name;
- + BOOL ret;
- + strcpy(name,name1);
- + if (strequal(name,"*")) {
- + strcpy(name,"\001\002__MSBROWSE__\002");
- + type = 1;
- + }
- + ret = name_query(name,type,True,False,ip,ipout);
- + if (!ret) return(False);
- + if (type != 1) return(True);
- +
- + name_status(name,type,*ipout,name1);
- + return(name1[0] != '*');
- +}
- +
- +/****************************************************************************
- +process a workgroup announce frame
- +****************************************************************************/
- +static void process_workgroup_announce(char *group,struct in_addr ip)
- +{
- + int i;
- + for (i=0;i<num_names;i++)
- + if (names[i].valid) {
- + if (names[i].name[0] == '*') {
- + StrnCpy(names[i].name,group,15);
- + names[i].master_ip = ip;
- + names[i].found_master = True;
- + names[i].count=0;
- + announce_host(i,myname,comment);
- + return;
- + }
- + if (names[i].isgroup && name_equal(names[i].name,group,0,0)) {
- + int j;
- + for (j=i;j<num_names;j++)
- + if (names[j].valid && names[j].isgroup && names[i].found_master &&
- + name_equal(names[i].name,group,0,0)) return;
- + names[i].master_ip = ip;
- + names[i].found_master = True;
- + names[i].count=0;
- + announce_host(i,myname,comment);
- + return;
- + }
- + }
- +}
- +
- +
- +/****************************************************************************
- +process a browse frame
- +****************************************************************************/
- +static void process_browse_packet(char *buf,int len)
- +{
- + char *p;
- + int command = CVAL(buf,0);
- + switch (command) {
- + case 0xc: /* workgroup announcement */
- + {
- + fstring group;
- + p = buf + 6;
- + StrnCpy(group,p,15);
- + DEBUG(2,("Got workgroup announce for %s (%s)\n",
- + group,inet_ntoa(lastip)));
- + process_workgroup_announce(group,lastip);
- + break;
- + }
- + }
- +
- +}
- +
- +/****************************************************************************
- +process udp 138 datagrams
- +****************************************************************************/
- +static void process_dgram(void)
- +{
- + pstring inbuf;
- + int len;
- + while (read_max_udp(ClientDGRAM,inbuf,sizeof(inbuf),1) > 4) {
- + char *p = inbuf;
- + len = RSVAL(inbuf,10);
- + p += 14;
- + p += name_len(p);
- + p += name_len(p);
- + p -= 4;
- + if (CVAL(p,smb_com) != SMBtrans) continue;
- + if (!strequal(smb_buf(p),"\\MAILSLOT\\BROWSE")) continue;
- + len = SVAL(p,smb_vwv11);
- + p = smb_base(p) + SVAL(p,smb_vwv12);
- + if (len <= 0) continue;
- + process_browse_packet(p,len);
- + }
- +}
- +
- +/****************************************************************************
- +a hook for registration of my own names
- +****************************************************************************/
- +static void do_registration_hook(void)
- +{
- + static int count = 0;
- + static time_t last_t=0;
- + time_t t = time(NULL);
- +
- + if (last_t && (t-last_t)<REGISTRATION_INTERVAL) return;
- + last_t = t;
- +
- + send_registration(myname,0x20,bcast_ip,myip,count>0,300000);
- + count++;
- +}
- +
- +/****************************************************************************
- +a hook for browsing handling - called every BROWSE_INTERVAL secs
- +****************************************************************************/
- +static void do_browse_hook(void)
- +{
- + static BOOL first = True;
- + int i;
- + static time_t last_t=0;
- + time_t t = time(NULL);
- +
- + if (last_t && (t-last_t)<browse_interval) return;
- + last_t = t;
- +
- + for (i=0;i<num_names;i++)
- + {
- + BOOL old_found_master = names[i].found_master;
- +
- + if (!NAMEVALID(i) || !ISGROUP(i)) continue;
- +
- + if (names[i].found_master) {
- + struct in_addr ip2;
- + announce_host(i,myname,comment);
- +
- + if (!name_query(names[i].name,0x1d,True,False,
- + names[i].master_ip,
- + &ip2)) {
- + DEBUG(2,("%s Master browser at %s failed to respond\n",
- + timestring(),
- + inet_ntoa(names[i].master_ip)));
- + names[i].found_master = False;
- + } else {
- + names[i].master_ip = ip2;
- + }
- + }
- +
- + if (!names[i].found_master) {
- + struct in_addr ip2;
- + names[i].found_master = find_master(names[i].name,names[i].ip,&ip2);
- +
- + if (names[i].found_master) {
- + names[i].master_ip = ip2;
- + DEBUG(1,("%s New master browser for %s at %s\n",
- + timestring(),
- + names[i].name,inet_ntoa(names[i].master_ip)));
- + names[i].count = 0;
- + announce_host(i,myname,comment);
- + }
- + }
- +
- + if (!names[i].found_master) {
- + int level = (old_found_master||first)?1:2;
- + DEBUG(level,("%s Failed to find a master browser for %s using %s\n",
- + timestring(),
- + names[i].name,inet_ntoa(names[i].ip)));
- + }
- + }
- + first = False;
- +}
- +
- +
- +/****************************************************************************
- + do a netbios name query to find someones IP
- + ****************************************************************************/
- +static BOOL name_query(char *name,int name_type, BOOL bcast,BOOL recurse,
- + struct in_addr to_ip, struct in_addr *ip)
- +{
- + BOOL found=False;
- + static uint16 name_trn_id = 0;
- + int retries = 3;
- + int retry_time = bcast?250:5000;
- + struct timeval tval;
- + struct packet_struct p;
- + struct packet_struct *p2;
- + struct nmb_packet *nmb = &p.packet.nmb;
- +
- + bzero((char *)&p,sizeof(p));
- +
- + if (!name_trn_id) name_trn_id = (time(NULL)%0x7FFF) + (getpid()%100);
- + name_trn_id = (name_trn_id+1) % 0x7FFF;
- +
- + nmb->header.name_trn_id = name_trn_id;
- + nmb->header.opcode = 0;
- + nmb->header.response = False;
- + nmb->header.nm_flags.bcast = bcast;
- + nmb->header.nm_flags.recursion_available = CanRecurse;
- + nmb->header.nm_flags.recursion_desired = recurse;
- + nmb->header.nm_flags.trunc = False;
- + nmb->header.nm_flags.authoritative = False;
- + nmb->header.rcode = 0;
- + nmb->header.qdcount = 1;
- + nmb->header.ancount = 0;
- + nmb->header.nscount = 0;
- + nmb->header.arcount = 0;
- +
- + strcpy(nmb->question.question_name.name,name);
- + strupper(nmb->question.question_name.name);
- + nmb->question.question_name.name_type = name_type;
- + strcpy(nmb->question.question_name.scope,scope);
- +
- + nmb->question.question_type = 0x20;
- + nmb->question.question_class = 0x1;
- +
- + p.ip = to_ip;
- + p.port = NMB_PORT;
- + p.fd = ClientNMB;
- + p.timestamp = time(NULL);
- + p.packet_type = NMB_PACKET;
- +
- + GetTimeOfDay(&tval);
- +
- + if (!send_packet(&p))
- + return(False);
- +
- + retries--;
- +
- + while (1)
- + {
- + struct timeval tval2;
- + GetTimeOfDay(&tval2);
- + if (TvalDiff(&tval,&tval2) > retry_time) {
- + if (!retries) break;
- + if (!found && !send_packet(&p))
- + return False;
- + GetTimeOfDay(&tval);
- + retries--;
- + }
- +
- + if ((p2=receive_packet(ClientNMB,NMB_PACKET,90)))
- + {
- + struct nmb_packet *nmb2 = &p2->packet.nmb;
- + if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- + !nmb2->header.response) {
- + /* its not for us - deal with it later */
- + queue_packet(p2);
- + continue;
- + }
- +
- + if (nmb2->header.opcode != 0 ||
- + nmb2->header.nm_flags.bcast ||
- + nmb2->header.rcode ||
- + !nmb2->header.ancount) {
- + /* XXXX what do we do with this? could be a redirect, but
- + we'll discard it for the moment */
- + free_packet(p2);
- + continue;
- + }
- +
- + putip((char *)ip,&nmb2->answers->rdata[2]);
- + DEBUG(2,("Got a positive name query response from %s",
- + inet_ntoa(p2->ip)));
- + DEBUG(2,(" (%s)\n",inet_ntoa(*ip)));
- + found=True; retries=0;
- + }
- + }
- +
- + return(found);
- +}
- +
- +
- +/****************************************************************************
- +reply to a name release
- +****************************************************************************/
- +static void reply_name_release(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *qname = nmb->question.question_name.name;
- + BOOL wildcard = (qname[0] == '*');
- + int name_type = nmb->question.question_name.name_type;
- + int nb_flags = nmb->additional->rdata[0];
- + struct packet_struct p2;
- + struct nmb_packet *nmb2;
- + struct res_rec answer_rec;
- + struct in_addr ip;
- + BOOL release_ok=False;
- + int reason=5;
- + int n;
- +
- + if (wildcard) return;
- +
- + putip((char *)&ip,&nmb->additional->rdata[2]);
- +
- + n = find_name(qname,name_type,True);
- + if (n>=0 && names[n].source == REGISTER &&
- + !memcmp((char *)&ip,(char *)&names[n].ip,sizeof(ip))) {
- + release_ok = True;
- + names[n].valid = False;
- + }
- +
- + /* Send a POSITIVE NAME RELEASE RESPONSE */
- + p2 = *p;
- + nmb2 = &p2.packet.nmb;
- +
- + nmb2->header.response = True;
- + nmb2->header.nm_flags.bcast = False;
- + nmb2->header.nm_flags.recursion_available = CanRecurse;
- + nmb2->header.nm_flags.trunc = False;
- + nmb2->header.nm_flags.authoritative = True;
- + nmb2->header.qdcount = 0;
- + nmb2->header.ancount = 1;
- + nmb2->header.nscount = 0;
- + nmb2->header.arcount = 0;
- + nmb2->header.rcode = release_ok?0:reason;
- +
- + nmb2->answers = &answer_rec;
- + bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- +
- + nmb2->answers->rr_name = nmb->question.question_name;
- + nmb2->answers->rr_type = nmb->question.question_type;
- + nmb2->answers->rr_class = nmb->question.question_class;
- + nmb2->answers->ttl = 0;
- + nmb2->answers->rdlength = 6;
- + nmb2->answers->rdata[0] = nb_flags;
- + putip(&nmb2->answers->rdata[2],(char *)&ip);
- +
- + send_packet(&p2);
- +}
- +
- +
- +
- +/****************************************************************************
- + reply to a reg request
- + **************************************************************************/
- +static void reply_name_reg(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *qname = nmb->question.question_name.name;
- + BOOL wildcard = (qname[0] == '*');
- + BOOL bcast = nmb->header.nm_flags.bcast;
- + int name_type = nmb->question.question_name.name_type;
- + int ttl = nmb->additional->ttl;
- + int nb_flags = nmb->additional->rdata[0];
- + struct packet_struct p2;
- + struct nmb_packet *nmb2;
- + struct res_rec answer_rec;
- + struct in_addr ip;
- +
- + if (wildcard) return;
- +
- + putip((char *)&ip,&nmb->additional->rdata[2]);
- +
- + if ((nb_flags&0x80) == 0 && (name_type != 0x1d)) {
- + int n = find_name(qname,name_type,True);
- + if (ttl==0) ttl = NMBD_MAX_TTL;
- + ttl = MIN(ttl,NMBD_MAX_TTL);
- +
- + if (n>=0 && names[n].source != REGISTER && names[n].source != DNS)
- + return;
- +
- + if (n<0)
- + n = add_name();
- + if (n<0) return;
- +
- + bzero(&names[n],sizeof(names[n]));
- +
- + StrnCpy(names[n].name,qname,15);
- + names[n].type = name_type;
- + names[n].unicast = !dns_serve || is_mynet(ip);
- + names[n].ip = ip;
- + names[n].valid = True;
- + names[n].ttl = ttl;
- + names[n].source = REGISTER;
- + names[n].start_time = p->timestamp;
- + }
- +
- + if (bcast) return;
- +
- + /* Send a POSITIVE NAME REGISTRATION RESPONSE */
- + /* a lot of fields get copied from the query. This gives us the IP
- + and port the reply will be sent to etc */
- + p2 = *p;
- + nmb2 = &p2.packet.nmb;
- +
- + nmb2->header.response = True;
- + nmb2->header.nm_flags.bcast = False;
- + nmb2->header.nm_flags.recursion_available = CanRecurse;
- + nmb2->header.nm_flags.trunc = False;
- + nmb2->header.nm_flags.authoritative = True;
- + nmb2->header.qdcount = 0;
- + nmb2->header.ancount = 1;
- + nmb2->header.nscount = 0;
- + nmb2->header.arcount = 0;
- +
- + nmb2->answers = &answer_rec;
- + bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- +
- + nmb2->answers->rr_name = nmb->question.question_name;
- + nmb2->answers->rr_type = nmb->question.question_type;
- + nmb2->answers->rr_class = nmb->question.question_class;
- +
- + /* we want them to refresh in case we die */
- + if (!ttl) ttl = 15*60;
- + ttl = MIN(ttl,15*60);
- +
- + nmb2->answers->ttl = ttl;
- + nmb2->answers->rdlength = 6;
- + nmb2->answers->rdata[0] = nb_flags;
- + putip(&nmb2->answers->rdata[2],(char *)&ip);
- +
- + send_packet(&p2);
- +}
- +
- +
- +/****************************************************************************
- +reply to a name status query
- +****************************************************************************/
- +static void reply_name_status(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *qname = nmb->question.question_name.name;
- + BOOL wildcard = (qname[0] == '*');
- + int name_type = nmb->question.question_name.name_type;
- + struct packet_struct p2;
- + struct nmb_packet *nmb2;
- + struct res_rec answer_rec;
- + char *buf;
- + int count,i;
- +
- + if (!wildcard) {
- + i = find_name(qname,name_type,False);
- +
- + if (i < 0)
- + return;
- + if (names[i].source != SELF && names[i].source != LMHOSTS)
- + return;
- + }
- +
- + /* Send a POSITIVE NAME STATUS RESPONSE */
- + /* a lot of fields get copied from the query. This gives us the IP
- + and port the reply will be sent to etc */
- + p2 = *p;
- + nmb2 = &p2.packet.nmb;
- +
- + nmb2->header.response = True;
- + nmb2->header.nm_flags.bcast = False;
- + nmb2->header.nm_flags.recursion_available = CanRecurse;
- + nmb2->header.nm_flags.trunc = False;
- + nmb2->header.nm_flags.authoritative = True; /* WfWg ignores
- + non-authoritative answers */
- + nmb2->header.qdcount = 0;
- + nmb2->header.ancount = 1;
- + nmb2->header.nscount = 0;
- + nmb2->header.arcount = 0;
- +
- + nmb2->answers = &answer_rec;
- + bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- +
- +
- + nmb2->answers->rr_name = nmb->question.question_name;
- + nmb2->answers->rr_type = nmb->question.question_type;
- + nmb2->answers->rr_class = nmb->question.question_class;
- + nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
- +
- + for (count=0,i=0;i<num_names;i++)
- + if (names[i].valid) count++;
- + count = MIN(count,400/18); /* XXXX hack, we should calculate exactly
- + how many will fit */
- +
- +
- + buf = &nmb2->answers->rdata[0];
- + SCVAL(buf,0,count);
- + buf += 1;
- +
- + for (i=0;i<num_names && count>0;i++)
- + if (names[i].valid)
- + {
- + bzero(buf,18);
- + strcpy(buf,names[i].name);
- + strupper(buf);
- + buf[15] = names[i].type;
- + buf += 16;
- + buf[0] = 0x4; /* active */
- + if (strequal(names[i].name,myname)) buf[0] |= 0x2; /* permanent */
- + if (ISGROUP(i)) buf[0] |= 0x80; /* group */
- + buf += 2;
- + count--;
- + }
- +
- + /* we should fill in more fields of the statistics structure */
- + bzero(buf,46);
- + putip(buf,(char *)&myip);
- + {
- + extern int num_good_sends,num_good_receives;
- + SIVAL(buf,20,num_good_sends);
- + SIVAL(buf,24,num_good_receives);
- + }
- +
- + buf += 46;
- +
- + nmb2->answers->rdlength = PTR_DIFF(buf,&nmb2->answers->rdata[0]);
- +
- + send_packet(&p2);
- +}
- +
- +
- +
- +/****************************************************************************
- +reply to a name query
- +****************************************************************************/
- +static void reply_name_query(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + char *qname = nmb->question.question_name.name;
- + BOOL wildcard = (qname[0] == '*');
- + BOOL bcast = nmb->header.nm_flags.bcast;
- + struct in_addr retip;
- + int name_type = nmb->question.question_name.name_type;
- + struct packet_struct p2;
- + struct nmb_packet *nmb2;
- + struct res_rec answer_rec;
- +
- + if (!wildcard) {
- + int i = find_name(qname,name_type,False);
- +
- + if (i < 0)
- + i = find_name(qname,name_type,True);
- +
- + if (i >= 0)
- + {
- + if (bcast && (names[i].unicast || names[i].source == REGISTER))
- + return;
- +
- + if (ISGROUP(i))
- + return;
- +
- + retip = names[i].ip;
- + }
- + else
- + {
- + if ((name_type!=0 && name_type!=0x3 && name_type!=0x20) ||
- + (bcast && !dns_serve)) {
- + return;
- + } else {
- + unsigned long a;
- +
- + a = interpret_addr(qname);
- + if (!a) return;
- +
- + /* here is where we might recurse */
- + putip((char *)&retip,(char *)&a);
- +
- + if (bcast && is_mynet(retip))
- + return;
- +
- + i = find_name(qname,name_type,True);
- + if (i < 0) {
- + if ((i=add_name())>=0) {
- + StrnCpy(names[i].name,qname,15);
- + names[i].type = name_type;
- + names[i].unicast = is_mynet(retip);
- + names[i].ip = retip;
- + names[i].valid = True;
- + names[i].ttl = 120; /* give it two minutes */
- + names[i].start_time = p->timestamp;
- + names[i].source = DNS;
- + }
- + }
- + }
- + DEBUG(2,(" sending positive reply (%s)\n",inet_ntoa(retip)));
- + }
- + } else {
- + retip = myip;
- + }
- +
- +
- + /* a lot of fields get copied from the query. This gives us the IP
- + and port the reply will be sent to etc */
- + p2 = *p;
- + nmb2 = &p2.packet.nmb;
- +
- + nmb2->header.response = True;
- + nmb2->header.nm_flags.bcast = False;
- + nmb2->header.nm_flags.recursion_available = CanRecurse;
- + nmb2->header.nm_flags.trunc = False;
- + nmb2->header.nm_flags.authoritative = True; /* WfWg ignores
- + non-authoritative answers */
- + nmb2->header.qdcount = 0;
- + nmb2->header.ancount = 1;
- + nmb2->header.nscount = 0;
- + nmb2->header.arcount = 0;
- +
- + nmb2->answers = &answer_rec;
- + bzero((char *)nmb2->answers,sizeof(*nmb2->answers));
- +
- + nmb2->answers->rr_name = nmb->question.question_name;
- + nmb2->answers->rr_type = nmb->question.question_type;
- + nmb2->answers->rr_class = nmb->question.question_class;
- + nmb2->answers->ttl = 0; /* XXX what ttl to answer with? */
- + nmb2->answers->rdlength = 6;
- + nmb2->answers->rdata[0] = 0; /* XXXX nbflags - what should this be? */
- + nmb2->answers->rdata[1] = 0;
- + putip(&nmb2->answers->rdata[2],(char *)&retip);
- +
- + send_packet(&p2);
- +}
- +
- +
- +
- +/* the global packet linked-list. incoming entries are added to the
- + end of this list. it is supposed to remain fairly short so we
- + won't bother with an end pointer. */
- +static struct packet_struct *packet_queue = NULL;
- +
- +
- +/*******************************************************************
- + queue a packet into the packet queue
- + ******************************************************************/
- +static void queue_packet(struct packet_struct *packet)
- +{
- + struct packet_struct *p;
- + if (!packet_queue) {
- + packet->prev = NULL;
- + packet->next = NULL;
- + packet_queue = packet;
- + return;
- + }
- +
- + /* find the bottom */
- + for (p=packet_queue;p->next;p=p->next) ;
- +
- + p->next = packet;
- + packet->next = NULL;
- + packet->prev = p;
- +}
- +
- +/****************************************************************************
- + process a nmb packet
- + ****************************************************************************/
- +static void process_nmb(struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- +
- + /* if this is a response then ignore it */
- + if (nmb->header.response) return;
- +
- + if (!nmb->header.nm_flags.bcast &&
- + nmb->header.opcode == 0x5 &&
- + nmb->header.qdcount==1 &&
- + nmb->header.arcount==1)
- + {
- + reply_name_reg(p);
- + return;
- + }
- +
- + if (nmb->header.opcode==0 &&
- + nmb->header.qdcount==1)
- + {
- + switch (nmb->question.question_type)
- + {
- + case 0x20:
- + reply_name_query(p);
- + break;
- +
- + case 0x21:
- + reply_name_status(p);
- + break;
- + }
- + return;
- + }
- +
- + if (!nmb->header.nm_flags.bcast &&
- + nmb->header.opcode == 6 &&
- + nmb->header.qdcount==1 &&
- + nmb->header.arcount==1)
- + {
- + reply_name_release(p);
- + return;
- + }
- +
- + if (!nmb->header.nm_flags.bcast &&
- + ((nmb->header.opcode == 8) || (nmb->header.opcode == 9)) &&
- + nmb->header.qdcount==1 &&
- + nmb->header.arcount==1)
- + {
- + reply_name_reg(p);
- + return;
- + }
- +}
- +
- +
- +
- +/*******************************************************************
- + run elements off the packet queue till its empty
- + ******************************************************************/
- +static void run_packet_queue(void)
- +{
- + struct packet_struct *p;
- +
- + while ((p=packet_queue)) {
- + switch (p->packet_type)
- + {
- + case NMB_PACKET:
- + process_nmb(p);
- + break;
- +
- + case DGRAM_PACKET:
- + /* process_dgram(p); */
- + break;
- + }
- +
- + packet_queue = packet_queue->next;
- + if (packet_queue) packet_queue->prev = NULL;
- + free_packet(p);
- + }
- +}
- +
- +
- +/****************************************************************************
- + The main select loop, listen for packets and respond
- + ***************************************************************************/
- +void process(void)
- +{
- + while (True)
- + {
- + fd_set fds;
- + int selrtn;
- + struct timeval timeout;
- +
- + do_registration_hook();
- + do_browse_hook();
- +
- + FD_ZERO(&fds);
- + FD_SET(ClientNMB,&fds);
- + FD_SET(ClientDGRAM,&fds);
- + timeout.tv_sec = NMBD_SELECT_LOOP;
- + timeout.tv_usec = 0;
- +
- + selrtn = sys_select(&fds,&timeout);
- +
- + if (FD_ISSET(ClientNMB,&fds)) {
- + struct packet_struct *packet = read_packet(ClientNMB,NMB_PACKET);
- + if (packet) queue_packet(packet);
- + }
- +
- + if (FD_ISSET(ClientDGRAM,&fds)) {
- + struct packet_struct *packet = read_packet(ClientDGRAM,DGRAM_PACKET);
- + if (packet) queue_packet(packet);
- + }
- +
- + run_packet_queue();
- + }
- +}
- +
- +
- +/****************************************************************************
- + open the socket communication
- +****************************************************************************/
- +static BOOL open_sockets(BOOL isdaemon,int port)
- +{
- + struct hostent *hp;
- +
- + /* get host info */
- + if ((hp = Get_Hostbyname(myhostname)) == 0)
- + {
- + DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
- + return False;
- + }
- +
- + if (isdaemon)
- + ClientNMB = open_socket_in(SOCK_DGRAM, port,*lookup?3:0);
- + else
- + ClientNMB = 0;
- +
- + ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
- +
- + if (ClientNMB == -1)
- + return(False);
- +
- + signal(SIGPIPE, SIGNAL_CAST sig_pipe);
- +
- + set_socket_options(ClientNMB,"SO_BROADCAST");
- + set_socket_options(ClientDGRAM,"SO_BROADCAST");
- + set_socket_options(ClientNMB,user_socket_options);
- +
- + DEBUG(3, ("Socket opened.\n"));
- + return True;
- +};
- +
- +
- +/****************************************************************************
- + initialise connect, service and file structs
- +****************************************************************************/
- +static BOOL init_structs(void )
- +{
- + if (!get_myname(myhostname,got_myip?NULL:&myip))
- + return(False);
- +
- + /* Read the broadcast address from the interface */
- + {
- + struct in_addr ip0,ip1,ip2;
- +
- + ip0 = myip;
- +
- + if (!(got_bcast && got_nmask))
- + {
- + get_broadcast(&ip0,&ip1,&ip2);
- +
- + if (!got_myip)
- + myip = ip0;
- +
- + if (!got_bcast)
- + bcast_ip = ip1;
- +
- + if (!got_nmask)
- + Netmask = ip2;
- + }
- +
- + DEBUG(1,("Using IP %s ",inet_ntoa(myip))); /* core dump reported
- + doing this. Why?? XXXXX */
- + DEBUG(1,("broadcast %s ",inet_ntoa(bcast_ip)));
- + DEBUG(1,("netmask %s\n",inet_ntoa(Netmask)));
- +
- + }
- +
- + if (! *myname) {
- + char *p;
- + strcpy(myname,myhostname);
- + p = strchr(myname,'.');
- + if (p) *p = 0;
- + }
- +
- + add_host_name(myname,0x20,&myip);
- + add_host_name(myname,0x0,&myip);
- + add_host_name(myname,0x3,&myip);
- +
- + return True;
- +}
- +
- +/****************************************************************************
- +usage on the program
- +****************************************************************************/
- +static void usage(char *pname)
- +{
- + DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
- +
- + printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
- + printf("Version %s\n",VERSION);
- + printf("\t-D become a daemon\n");
- + printf("\t-P passive only. don't respond\n");
- + printf("\t-R only reply to queries, don't actively send claims\n");
- + printf("\t-p port listen on the specified port\n");
- + printf("\t-d debuglevel set the debuglevel\n");
- + printf("\t-l log basename. Basename for log/debug files\n");
- + printf("\t-n netbiosname. the netbios name to advertise for this host\n");
- + printf("\t-B broadcast address the address to use for broadcasts\n");
- + printf("\t-N netmask the netmask to use for subnet determination\n");
- + printf("\t-L name lookup this netbios name then exit\n");
- + printf("\t-S serve queries via DNS if not on the same subnet\n");
- + printf("\t-H hosts file load a netbios hosts file\n");
- + printf("\t-G group name add a group name to be part of\n");
- + printf("\t-b toggles browsing support (defaults to on)\n");
- + printf("\t-M group name searches for a master browser for the given group\n");
- + printf("\t-T interval sets the browse announcement interval in seconds\n");
- + printf("\t-C comment sets the machine comment that appears in browse lists\n");
- + printf("\n");
- +}
- +
- +
- +/****************************************************************************
- + main program
- +****************************************************************************/
- +int main(int argc,char *argv[])
- +{
- + int port = NMB_PORT;
- + int opt;
- + unsigned int lookup_type = 0;
- + extern FILE *dbf;
- + extern char *optarg;
- +
- + *lookup = *host_file = 0;
- +
- + TimeInit();
- +
- + charset_initialise();
- +
- + strcpy(debugf,NMBLOGFILE);
- +
- +#ifdef LMHOSTSFILE
- + strcpy(host_file,LMHOSTSFILE);
- +#endif
- +
- + /* this is for people who can't start the program correctly */
- + while (argc > 1 && (*argv[1] != '-'))
- + {
- + argv++;
- + argc--;
- + }
- +
- + fault_setup(fault_continue);
- +
- + signal(SIGHUP,SIGNAL_CAST sig_hup);
- +
- +
- + while ((opt = getopt (argc, argv, "T:O:M:I:C:bAL:i:B:N:Rn:l:d:Dp:hPSH:G:")) != EOF)
- + switch (opt)
- + {
- + case 'T':
- + browse_interval = atoi(optarg);
- + browse_interval = MAX(browse_interval,10);
- + break;
- + case 'O':
- + strcpy(user_socket_options,optarg);
- + break;
- + case 'C':
- + strcpy(comment,optarg);
- + break;
- + case 'G':
- + add_group_name(optarg);
- + break;
- + case 'A':
- + dns_serve = True;
- + break;
- + case 'H':
- + strcpy(host_file,optarg);
- + break;
- + case 'I':
- + {
- + unsigned long a = interpret_addr(optarg);
- + putip((char *)&myip,(char *)&a);
- + got_myip = True;
- + }
- + break;
- + case 'B':
- + {
- + unsigned long a = interpret_addr(optarg);
- + putip((char *)&bcast_ip,(char *)&a);
- + got_bcast = True;
- + }
- + break;
- + case 'N':
- + {
- + unsigned long a = interpret_addr(optarg);
- + putip((char *)&Netmask,(char *)&a);
- + got_nmask = True;
- + }
- + break;
- + case 'n':
- + strcpy(myname,optarg);
- + break;
- + case 'P':
- + {
- + extern BOOL passive;
- + passive = True;
- + }
- + break;
- + case 'S':
- + dns_serve = !dns_serve;
- + break;
- + case 'l':
- + sprintf(debugf,"%s.nmb",optarg);
- + break;
- + case 'i':
- + strcpy(scope,optarg);
- + strupper(scope);
- + break;
- + case 'L':
- + strcpy(lookup,optarg);
- + break;
- + case 'M':
- + if (*optarg == '-') {
- + strcpy(lookup,"\01\02__MSBROWSE__\02");
- + lookup_type = 1;
- + } else {
- + strcpy(lookup,optarg);
- + lookup_type = 0x1d;
- + }
- + break;
- + case 'D':
- + is_daemon = True;
- + break;
- + case 'd':
- + DEBUGLEVEL = atoi(optarg);
- + break;
- + case 'p':
- + port = atoi(optarg);
- + break;
- + case 'h':
- + usage(argv[0]);
- + exit(0);
- + break;
- + default:
- + usage(argv[0]);
- + exit(1);
- + }
- +
- +
- + if (*lookup)
- + DEBUGLEVEL++;
- +
- + if (DEBUGLEVEL > 10)
- + {
- + extern FILE *login,*logout;
- + pstring fname;
- + sprintf(fname,"%s.in",debugf);
- + login = fopen(fname,"w");
- + sprintf(fname,"%s.out",debugf);
- + logout = fopen(fname,"w");
- + }
- +
- + if (*lookup)
- + {
- + if (dbf)
- + fclose(dbf);
- + dbf = stdout;
- + }
- +
- + DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
- + DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
- +
- + if (*host_file)
- + {
- + load_hosts_file(host_file);
- + DEBUG(3,("Loaded hosts file\n"));
- + }
- +
- + init_structs();
- +
- + if (*lookup) {
- + BOOL bcast = True;
- + int retries = 2;
- + char *p = strchr(lookup,'#');
- + struct in_addr ip;
- + if (p) {
- + *p = 0;
- + sscanf(p+1,"%x",&lookup_type);
- + bcast = False;
- + retries = 1;
- + }
- + if (!open_sockets(True,port)) return(1);
- + while (retries--)
- + if (name_query(lookup,lookup_type,bcast,True,bcast_ip,&ip)) {
- + printf("%s %s\n",inet_ntoa(ip),lookup);
- + name_status(lookup,lookup_type,ip,NULL);
- + return(0);
- + }
- + printf("couldn't find name %s\n",lookup);
- + return(0);
- + }
- +
- + if (!*comment)
- + strcpy(comment,"Samba %v");
- + string_sub(comment,"%v",VERSION);
- + string_sub(comment,"%h",myhostname);
- +
- + check_names();
- +
- + DEBUG(3,("Checked names\n"));
- +
- + dump_names();
- +
- + DEBUG(3,("Dumped names\n"));
- +
- + if (!is_daemon && !is_a_socket(0)) {
- + DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- + is_daemon = True;
- + }
- +
- +
- + if (is_daemon) {
- + DEBUG(2,("%s becoming a daemon\n",timestring()));
- + become_daemon();
- + }
- +
- +
- + DEBUG(3,("Opening sockets\n"));
- +
- + if (open_sockets(is_daemon,port))
- + {
- + process();
- + close_sockets();
- + }
- +
- + if (dbf)
- + fclose(dbf);
- + return(0);
- +}
- diff -u -r --new-file last-version/source/nmblib.c samba-1.9.14p3/source/nmblib.c
- --- last-version/source/nmblib.c Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/nmblib.c Tue Nov 7 22:25:10 1995
- @@ -0,0 +1,504 @@
- +/*
- + Unix SMB/Netbios implementation.
- + Version 1.9.
- + NBT netbios routines and daemon - version 2
- + Copyright (C) Andrew Tridgell 1994-1995
- +
- + This program is free software; you can redistribute it and/or modify
- + it under the terms of the GNU General Public License as published by
- + the Free Software Foundation; either version 2 of the License, or
- + (at your option) any later version.
- +
- + This program is distributed in the hope that it will be useful,
- + but WITHOUT ANY WARRANTY; without even the implied warranty of
- + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- + GNU General Public License for more details.
- +
- + You should have received a copy of the GNU General Public License
- + along with this program; if not, write to the Free Software
- + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- +
- +*/
- +
- +#include "includes.h"
- +#include "nameserv.h"
- +
- +extern int DEBUGLEVEL;
- +
- +int num_good_sends=0;
- +int num_good_receives=0;
- +
- +/*******************************************************************
- + handle "compressed" name pointers
- + ******************************************************************/
- +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
- + BOOL *got_pointer,int *ret)
- +{
- + int loop_count=0;
- +
- + while ((ubuf[*offset] & 0xC0) == 0xC0) {
- + if (!*got_pointer) (*ret) += 2;
- + (*got_pointer)=True;
- + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
- + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
- + return(False);
- + }
- + }
- + return(True);
- +}
- +
- +/*******************************************************************
- + parse a nmb name from "compressed" format to something readable
- + return the space taken by the name, or 0 if the name is invalid
- + ******************************************************************/
- +static int parse_nmb_name(char *inbuf,int offset,int length,
- + struct nmb_name *name)
- +{
- + int m,n=0;
- + unsigned char *ubuf = (unsigned char *)inbuf;
- + int ret = 0;
- + BOOL got_pointer=False;
- +
- + if (length - offset < 2) return(0);
- +
- + /* handle initial name pointers */
- + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
- +
- + m = ubuf[offset];
- +
- + if (!m) return(0);
- + if ((m & 0xC0) || offset+m+2 > length) return(0);
- +
- + bzero((char *)name,sizeof(*name));
- +
- + /* the "compressed" part */
- + if (!got_pointer) ret += m + 2;
- + offset++;
- + while (m) {
- + unsigned char c1,c2;
- + c1 = ubuf[offset++]-'A';
- + c2 = ubuf[offset++]-'A';
- + if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
- + name->name[n++] = (c1<<4) | c2;
- + m -= 2;
- + }
- + name->name[n] = 0;
- +
- + if (n==16) {
- + /* parse out the name type,
- + its always in the 16th byte of the name */
- + name->name_type = name->name[15];
- +
- + /* remove trailing spaces */
- + name->name[15] = 0;
- + n = 14;
- + while (n && name->name[n]==' ') name->name[n--] = 0;
- + }
- +
- + /* now the domain parts (if any) */
- + n = 0;
- + while ((m=ubuf[offset])) {
- + /* we can have pointers within the domain part as well */
- + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
- +
- + if (!got_pointer) ret += m+1;
- + if (n) name->scope[n++] = '.';
- + if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
- + offset++;
- + while (m--) name->scope[n++] = (char)ubuf[offset++];
- + }
- + name->scope[n++] = 0;
- +
- + return(ret);
- +}
- +
- +
- +/*******************************************************************
- + put a compressed nmb name into a buffer. return the length of the
- + compressed name
- + ******************************************************************/
- +static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
- +{
- + int ret,m;
- + char buf1[16];
- + char *p;
- +
- + sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
- + buf[offset] = 0x20;
- +
- + ret = 34;
- +
- + for (m=0;m<16;m++) {
- + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
- + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
- + }
- + offset += 33;
- +
- + buf[offset] = 0;
- +
- + if (name->scope[0]) {
- + /* XXXX this scope handling needs testing */
- + ret += strlen(name->scope) + 1;
- + strcpy(&buf[offset+1],name->scope);
- +
- + p = &buf[offset+1];
- + while ((p = strchr(p,'.'))) {
- + buf[offset] = PTR_DIFF(p,&buf[offset]);
- + offset += buf[offset];
- + p = &buf[offset+1];
- + }
- + buf[offset] = strlen(&buf[offset+1]);
- + }
- +
- + return(ret);
- +}
- +
- +
- +/*******************************************************************
- + allocate are parse some resource records
- + ******************************************************************/
- +static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
- + struct res_rec **recs,
- + int count)
- +{
- + int i;
- + *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
- + if (!*recs) return(False);
- +
- + bzero(*recs,sizeof(**recs)*count);
- +
- + for (i=0;i<count;i++) {
- + int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
- + (*offset) += l;
- + if (!l || (*offset)+10 > length) {
- + free(*recs);
- + return(False);
- + }
- + (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
- + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
- + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
- + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
- + (*offset) += 10;
- + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
- + (*offset)+(*recs)[i].rdlength > length) {
- + free(*recs);
- + return(False);
- + }
- + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
- + (*offset) += (*recs)[i].rdlength;
- + }
- + return(True);
- +}
- +
- +/*******************************************************************
- + put a resource record into a packet
- + ******************************************************************/
- +static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
- +{
- + int ret=0;
- + int i;
- +
- + for (i=0;i<count;i++) {
- + int l = put_nmb_name(buf,offset,&recs[i].rr_name);
- + offset += l;
- + ret += l;
- + RSSVAL(buf,offset,recs[i].rr_type);
- + RSSVAL(buf,offset+2,recs[i].rr_class);
- + RSIVAL(buf,offset+4,recs[i].ttl);
- + RSSVAL(buf,offset+8,recs[i].rdlength);
- + memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
- + offset += 10+recs[i].rdlength;
- + ret += 10+recs[i].rdlength;
- + }
- +
- + return(ret);
- +}
- +
- +/*******************************************************************
- + parse a dgram packet. Return False if the packet can't be parsed
- + or is invalid for some reason, True otherwise
- + ******************************************************************/
- +static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
- +{
- + int offset;
- +
- + bzero((char *)dgram,sizeof(*dgram));
- +
- + if (length < 14) return(False);
- +
- + dgram->header.res = RSVAL(inbuf,0);
- + dgram->header.id = RSVAL(inbuf,2);
- + putip((char *)&dgram->header.ip,inbuf+4);
- + dgram->header.port = RSVAL(inbuf,8);
- + dgram->header.length = RSVAL(inbuf,10);
- + dgram->header.res2 = RSVAL(inbuf,12);
- +
- + offset = 14;
- + offset += parse_nmb_name(inbuf,offset,length,&dgram->header.source_name);
- + offset += parse_nmb_name(inbuf,offset,length,&dgram->header.dest_name);
- +
- + if (offset >= length || (length-offset > sizeof(dgram->smb_data)))
- + return(False);
- +
- + dgram->smbsize = length-offset;
- + memcpy(dgram->smb_data,inbuf+offset,dgram->smbsize);
- +
- + return(True);
- +}
- +
- +
- +/*******************************************************************
- + parse a nmb packet. Return False if the packet can't be parsed
- + or is invalid for some reason, True otherwise
- + ******************************************************************/
- +static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
- +{
- + int nm_flags,offset;
- +
- + bzero((char *)nmb,sizeof(*nmb));
- +
- + if (length < 12) return(False);
- +
- + /* parse the header */
- + nmb->header.name_trn_id = RSVAL(inbuf,0);
- + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
- + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
- + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
- + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
- + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
- + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
- + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
- + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
- + nmb->header.rcode = CVAL(inbuf,3) & 0xF;
- + nmb->header.qdcount = RSVAL(inbuf,4);
- + nmb->header.ancount = RSVAL(inbuf,6);
- + nmb->header.nscount = RSVAL(inbuf,8);
- + nmb->header.arcount = RSVAL(inbuf,10);
- +
- + if (nmb->header.qdcount) {
- + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
- + if (!offset) return(False);
- +
- + if (length - (12+offset) < 4) return(False);
- + nmb->question.question_type = RSVAL(inbuf,12+offset);
- + nmb->question.question_class = RSVAL(inbuf,12+offset+2);
- +
- + offset += 12+4;
- + } else {
- + offset = 12;
- + }
- +
- + /* and any resource records */
- + if (nmb->header.ancount &&
- + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
- + nmb->header.ancount))
- + return(False);
- +
- + if (nmb->header.nscount &&
- + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
- + nmb->header.nscount))
- + return(False);
- +
- + if (nmb->header.arcount &&
- + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
- + nmb->header.arcount))
- + return(False);
- +
- + return(True);
- +}
- +
- +/*******************************************************************
- + free up any resources associated with an nmb packet
- + ******************************************************************/
- +void free_nmb_packet(struct nmb_packet *nmb)
- +{
- + if (nmb->answers) free(nmb->answers);
- + if (nmb->nsrecs) free(nmb->nsrecs);
- + if (nmb->additional) free(nmb->additional);
- +}
- +
- +/*******************************************************************
- + free up any resources associated with a packet
- + ******************************************************************/
- +void free_packet(struct packet_struct *packet)
- +{
- + free_nmb_packet(&packet->packet.nmb);
- + free(packet);
- +}
- +
- +/*******************************************************************
- + read a packet from a socket and parse it, returning a packet ready
- + to be used or put on the queue. This assumes a UDP socket
- + ******************************************************************/
- +struct packet_struct *read_packet(int fd,enum packet_type packet_type)
- +{
- + extern struct in_addr lastip;
- + extern int lastport;
- + struct packet_struct *packet;
- + char buf[MAX_DGRAM_SIZE];
- + int length;
- + BOOL ok=False;
- +
- + length = read_udp_socket(fd,buf,sizeof(buf));
- + if (length < MIN_DGRAM_SIZE) return(NULL);
- +
- + packet = (struct packet_struct *)malloc(sizeof(*packet));
- + if (!packet) return(NULL);
- +
- + packet->next = NULL;
- + packet->prev = NULL;
- + packet->ip = lastip;
- + packet->port = lastport;
- + packet->fd = fd;
- + packet->timestamp = time(NULL);
- + packet->packet_type = packet_type;
- + switch (packet_type)
- + {
- + case NMB_PACKET:
- + ok = parse_nmb(buf,length,&packet->packet.nmb);
- + break;
- +
- + case DGRAM_PACKET:
- + ok = parse_dgram(buf,length,&packet->packet.dgram);
- + break;
- + }
- + if (!ok) {
- + free(packet);
- + return(NULL);
- + }
- +
- + num_good_receives++;
- +
- + return(packet);
- +}
- +
- +
- +/*******************************************************************
- + send a udp packet on a already open socket
- + ******************************************************************/
- +static BOOL send_udp(int fd,char *buf,int len,struct in_addr *ip,int port)
- +{
- + BOOL ret;
- + struct sockaddr_in sock_out;
- +
- + /* set the address and port */
- + bzero((char *)&sock_out,sizeof(sock_out));
- + putip((char *)&sock_out.sin_addr,(char *)ip);
- + sock_out.sin_port = htons( port );
- + sock_out.sin_family = AF_INET;
- +
- + DEBUG(3,("sending a packet of len %d to (%s) on port 137 of type DGRAM\n",
- + len,inet_ntoa(*ip)));
- +
- + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
- + sizeof(sock_out)) >= 0);
- +
- + if (!ret)
- + DEBUG(0,("Send packet failed. ERRNO=%d\n",errno));
- +
- + if (ret)
- + num_good_sends++;
- +
- + return(ret);
- +}
- +
- +
- +/*******************************************************************
- + build a nmb packet ready for sending
- +
- + XXXX this currently relies on not being passed something that expands
- + to a packet too big for the buffer. Eventually this should be
- + changed to set the trunc bit so the receiver can request the rest
- + via tcp (when that becomes supported)
- + ******************************************************************/
- +static int build_nmb(char *buf,struct packet_struct *p)
- +{
- + struct nmb_packet *nmb = &p->packet.nmb;
- + unsigned char *ubuf = (unsigned char *)buf;
- + int offset=0;
- +
- + /* put in the header */
- + RSSVAL(ubuf,offset,nmb->header.name_trn_id);
- + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
- + if (nmb->header.response) ubuf[offset+2] |= (1<<7);
- + if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4;
- + if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
- + if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
- + if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80;
- + if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
- + ubuf[offset+3] |= (nmb->header.rcode & 0xF);
- + RSSVAL(ubuf,offset+4,nmb->header.qdcount);
- + RSSVAL(ubuf,offset+6,nmb->header.ancount);
- + RSSVAL(ubuf,offset+8,nmb->header.nscount);
- + RSSVAL(ubuf,offset+10,nmb->header.arcount);
- +
- + offset += 12;
- + if (nmb->header.qdcount) {
- + /* XXXX this doesn't handle a qdcount of > 1 */
- + offset += put_nmb_name(ubuf,offset,&nmb->question.question_name);
- + RSSVAL(ubuf,offset,nmb->question.question_type);
- + RSSVAL(ubuf,offset+2,nmb->question.question_class);
- + offset += 4;
- + }
- +
- + if (nmb->header.ancount)
- + offset += put_res_rec(ubuf,offset,nmb->answers,nmb->header.ancount);
- +
- + if (nmb->header.nscount)
- + offset += put_res_rec(ubuf,offset,nmb->nsrecs,nmb->header.nscount);
- +
- + if (nmb->header.arcount)
- + offset += put_res_rec(ubuf,offset,nmb->additional,nmb->header.arcount);
- +
- + return(offset);
- +}
- +
- +
- +/*******************************************************************
- + send a packet_struct
- + ******************************************************************/
- +BOOL send_packet(struct packet_struct *p)
- +{
- + char buf[1024];
- + int len=0;
- +
- + bzero(buf,sizeof(buf));
- +
- + switch (p->packet_type)
- + {
- + case NMB_PACKET:
- + len = build_nmb(buf,p);
- + break;
- +
- + case DGRAM_PACKET:
- + /* len = build_dgram(buf,p); */
- + break;
- + }
- +
- + if (!len) return(False);
- +
- + return(send_udp(p->fd,buf,len,&p->ip,p->port));
- +}
- +
- +/****************************************************************************
- + receive a packet with timeout on a open UDP filedescriptor
- + The timeout is in milliseconds
- + ***************************************************************************/
- +struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
- +{
- + fd_set fds;
- + struct timeval timeout;
- +
- + FD_ZERO(&fds);
- + FD_SET(fd,&fds);
- + timeout.tv_sec = t/1000;
- + timeout.tv_usec = 1000*(t%1000);
- +
- + sys_select(&fds,&timeout);
- +
- + if (FD_ISSET(fd,&fds))
- + return(read_packet(fd,type));
- +
- + return(NULL);
- +}
- +
- diff -u -r --new-file last-version/source/password.c samba-1.9.14p3/source/password.c
- --- last-version/source/password.c Fri Sep 22 10:37:06 1995
- +++ samba-1.9.14p3/source/password.c Sun Nov 5 15:51:20 1995
- @@ -568,7 +568,7 @@
- /****************************************************************************
- check if a username/password is OK
- ****************************************************************************/
- -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
- +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password)
- {
- pstring pass2;
- int level = lp_passwordlevel();
- @@ -641,6 +641,26 @@
- return(False);
- }
-
- + if(Protocol >= PROTOCOL_NT1 && is_nt_password)
- + {
- + /* We have the NT MD4 hash challenge available - see if we can
- + use it (ie. does it exist in the smbpasswd file).
- + */
- + if(smb_pass->smb_nt_passwd != NULL)
- + {
- + DEBUG(4,("Checking NT MD4 password\n"));
- + if(smb_password_check(password, smb_pass->smb_nt_passwd, challenge))
- + {
- + update_protected_database(user,True);
- + return(True);
- + }
- + DEBUG(4,("NT MD4 password check failed\n"));
- + return (False);
- + }
- + }
- +
- + /* Try against the lanman password */
- +
- if(smb_password_check(password, smb_pass->smb_passwd, challenge))
- {
- update_protected_database(user,True);
- @@ -819,7 +839,7 @@
- while (getnetgrent(&host, &user, &domain)) {
- if (user) {
- if (user_ok(user, snum) &&
- - password_ok(user,password,pwlen,NULL)) {
- + password_ok(user,password,pwlen,NULL,False)) {
- endnetgrent();
- return(user);
- }
- @@ -841,7 +861,7 @@
- static fstring name;
- strcpy(name,*member);
- if (user_ok(name,snum) &&
- - password_ok(name,password,pwlen,NULL))
- + password_ok(name,password,pwlen,NULL,False))
- return(&name[0]);
- member++;
- }
- @@ -854,7 +874,7 @@
- while (pwd = getpwent ()) {
- if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
- /* This Entry have PASSWORD and same GID then check pwd */
- - if (password_ok(NULL, password, pwlen, pwd)) {
- + if (password_ok(NULL, password, pwlen, pwd,False)) {
- strcpy(tm, pwd->pw_name);
- endpwent ();
- return tm;
- @@ -905,14 +925,14 @@
-
- /* check the given username and password */
- if (!ok && (*user) && user_ok(user,snum)) {
- - ok = password_ok(user,password, pwlen, NULL);
- + ok = password_ok(user,password, pwlen, NULL, False);
- if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
- }
-
- /* check for a previously registered guest username */
- if (!ok && (vuid >= 0) && validated_users[vuid].guest) {
- if (user_ok(validated_users[vuid].name,snum) &&
- - password_ok(validated_users[vuid].name, password, pwlen, NULL)) {
- + password_ok(validated_users[vuid].name, password, pwlen, NULL, False)) {
- strcpy(user, validated_users[vuid].name);
- validated_users[vuid].guest = False;
- DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
- @@ -936,7 +956,7 @@
- strcpy(user2,auser);
- if (!user_ok(user2,snum)) continue;
-
- - if (password_ok(user2,password, pwlen, NULL)) {
- + if (password_ok(user2,password, pwlen, NULL, False)) {
- ok = True;
- strcpy(user,user2);
- DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
- @@ -988,7 +1008,7 @@
- fstring user2;
- strcpy(user2,auser);
- if (user_ok(user2,snum) &&
- - password_ok(user2,password,pwlen,NULL))
- + password_ok(user2,password,pwlen,NULL, False))
- {
- ok = True;
- strcpy(user,user2);
- diff -u -r --new-file last-version/source/printing.c samba-1.9.14p3/source/printing.c
- --- last-version/source/printing.c Thu Nov 2 09:59:36 1995
- +++ samba-1.9.14p3/source/printing.c Mon Nov 6 16:53:58 1995
- @@ -83,7 +83,7 @@
- the subshell causes a "cd" to be executed.
- Only use the full path if there isn't a / preceding the %s */
- if (iOffset==0 || syscmd[iOffset-1] != '/') {
- - StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename));
- + StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1);
- trim_string(filename,"","/");
- strcat(filename,"/");
- strcat(filename,filename1);
- @@ -143,7 +143,10 @@
- lpq_reset(snum);
- }
-
- +static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
-
- +
- /*******************************************************************
- process time fields
- ********************************************************************/
- @@ -156,8 +159,6 @@
- struct tm *t;
- int i, day, hour, min, sec;
- char *c;
- - const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err" };
-
- for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
- if (i<12) {
- @@ -186,7 +187,6 @@
- jobtime = mktime(t);
- }
- }
- - jobtime += GMT_TO_LOCAL*TimeDiff(jobtime);
- return jobtime;
- }
-
- diff -u -r --new-file last-version/source/reply.c samba-1.9.14p3/source/reply.c
- --- last-version/source/reply.c Sat Nov 4 22:32:47 1995
- +++ samba-1.9.14p3/source/reply.c Mon Nov 6 16:14:59 1995
- @@ -290,6 +290,9 @@
- uint32 smb_sesskey;
- int smb_apasslen;
- pstring smb_apasswd;
- + int smb_ntpasslen = 0;
- + pstring smb_ntpasswd;
- + BOOL valid_nt_password = False;
- pstring user;
- BOOL guest=False;
-
- @@ -316,10 +319,11 @@
- if (passlen2 > 256) passlen2 = 0; /* I don't know why NT gives weird
- lengths sometimes */
- if(doencrypt) {
- - /* Use the lanman2 password for now until the NT md4 password
- - is worked out. */
- + /* Save the lanman2 password and the NT md4 password. */
- smb_apasslen = passlen1;
- memcpy(smb_apasswd,p,smb_apasslen);
- + smb_ntpasslen = passlen2;
- + memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
- } else {
- /* for Win95 */
- if (passlen1 > passlen2) {
- @@ -359,8 +363,17 @@
- guest = True;
-
- /* now check if it's a valid username/password */
- - if (!guest && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
- + /* If an NT password was supplied try and validate with that
- + first. This is superior as the passwords are mixed case 128 length unicode */
- + if(smb_ntpasslen && !guest)
- {
- + if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL,True))
- + DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
- + else
- + valid_nt_password = True;
- + }
- + if (!valid_nt_password && !guest && !password_ok(user,smb_apasswd,smb_apasslen,NULL,False))
- + {
- #if !GUEST_SESSSETUP
- if (lp_security() >= SEC_USER)
- return(ERROR(ERRSRV,ERRbadpw));
- @@ -456,7 +469,7 @@
- mode = SVAL(inbuf,smb_vwv0);
-
- if (check_name(name,cnum))
- - ok = directory_exist(name);
- + ok = directory_exist(name,NULL);
-
- if (!ok)
- return(ERROR(ERRDOS,ERRbadpath));
- @@ -520,7 +533,7 @@
- outsize = set_message(outbuf,10,0,True);
-
- SSVAL(outbuf,smb_vwv0,mode);
- - SIVAL(outbuf,smb_vwv1,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
- + put_dos_date3(outbuf,smb_vwv1,mtime);
- SIVAL(outbuf,smb_vwv3,size);
-
- if (Protocol >= PROTOCOL_NT1) {
- @@ -555,14 +568,14 @@
- unix_convert(fname,cnum);
-
- mode = SVAL(inbuf,smb_vwv0);
- - mtime = IVAL(inbuf,smb_vwv1);
- + mtime = make_unix_date3(inbuf+smb_vwv1);
-
- - if (directory_exist(fname))
- + if (directory_exist(fname,NULL))
- mode |= aDIR;
- if (check_name(fname,cnum))
- ok = (dos_chmod(cnum,fname,mode) == 0);
- - if (ok && mtime != 0)
- - ok = set_filetime(fname,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
- + if (ok)
- + ok = set_filetime(fname,mtime);
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- @@ -930,7 +943,7 @@
- outsize = set_message(outbuf,7,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,fmode);
- - SIVAL(outbuf,smb_vwv2,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
- + put_dos_date3(outbuf,smb_vwv2,mtime);
- SIVAL(outbuf,smb_vwv4,size);
- SSVAL(outbuf,smb_vwv6,rmode);
-
- @@ -955,7 +968,7 @@
- #if 0
- int open_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- - uint32 smb_time = IVAL(inbuf,smb_vwv6);
- + uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
- #endif
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- int unixmode;
- @@ -1007,7 +1020,7 @@
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
- SSVAL(outbuf,smb_vwv2,fnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- - SIVAL(outbuf,smb_vwv4,mtime + GMT_TO_LOCAL * TimeDiff(mtime));
- + put_dos_date3(outbuf,smb_vwv4,mtime);
- SIVAL(outbuf,smb_vwv6,size);
- SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,smb_action);
- @@ -1918,15 +1931,12 @@
- err = Files[fnum].wbmpx_ptr->wr_error;
- }
-
- - mtime = IVAL(inbuf,smb_vwv1);
- + mtime = make_unix_date3(inbuf+smb_vwv1);
-
- close_file(fnum);
-
- /* try and set the date */
- - if (mtime == 0 || mtime == -1)
- - DEBUG(5,("not setting null date\n"));
- - else
- - set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
- + set_filetime(Files[fnum].name,mtime);
-
- /* We have a cached error */
- if(eclass || err)
- @@ -1961,7 +1971,7 @@
-
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- - mtime = IVAL(inbuf,smb_vwv4);
- + mtime = make_unix_date3(inbuf+smb_vwv4);
- data = smb_buf(inbuf) + 1;
-
- if (is_locked(fnum,cnum,numtowrite,startpos))
- @@ -1973,10 +1983,7 @@
-
- close_file(fnum);
-
- - if (mtime == 0 || mtime == -1)
- - DEBUG(5,("not setting null date\n"));
- - else
- - set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff(mtime));
- + set_filetime(Files[fnum].name,mtime);
-
- DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
- timestring(),fnum,cnum,numtowrite,nwritten,
- @@ -2516,6 +2523,7 @@
- strcat(directory,mask);
- if (resolve_wildcards(directory,newname) &&
- can_rename(directory,cnum) &&
- + !file_exist(newname,NULL) &&
- !sys_rename(directory,newname)) count++;
- if (!count) exists = file_exist(directory,NULL);
- } else {
- @@ -2545,6 +2553,7 @@
- if (!can_rename(fname,cnum)) continue;
- strcpy(destname,newname);
- if (resolve_wildcards(fname,destname) &&
- + !file_exist(destname,NULL) &&
- !sys_rename(fname,destname)) count++;
- DEBUG(3,("reply_mv : doing rename on %s -> %s\n",fname,destname));
- }
- @@ -2588,7 +2597,7 @@
- ok = True;
- else
- {
- - ok = directory_exist(newdir);
- + ok = directory_exist(newdir,NULL);
- if (ok)
- string_set(&Connections[cnum].connectpath,newdir);
- }
- @@ -2943,12 +2952,8 @@
- /* Convert the DOS times into unix times. Ignore create
- time as UNIX can't set this.
- */
- -
- - /* XXXX - should this include the DST offset? */
- - unix_times.actime = make_unix_date2(inbuf+smb_vwv3,False);
- - unix_times.modtime = make_unix_date2(inbuf+smb_vwv5,False);
- - unix_times.actime += LOCAL_TO_GMT*TimeDiff(unix_times.actime);
- - unix_times.modtime += LOCAL_TO_GMT*TimeDiff(unix_times.modtime);
- + unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
- + unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
-
- /* Set the date on this file */
- if(sys_utime(Files[fnum].name, &unix_times))
- diff -u -r --new-file last-version/source/server.c samba-1.9.14p3/source/server.c
- --- last-version/source/server.c Sat Nov 4 22:11:05 1995
- +++ samba-1.9.14p3/source/server.c Tue Nov 7 18:24:54 1995
- @@ -347,7 +347,8 @@
- (strequal(dname,".") || strequal(dname,"..")))
- continue;
-
- - if (!name_convert(name2,dname,False,snum)) continue;
- + strcpy(name2,dname);
- + if (!name_map_mangle(name2,False,snum)) continue;
-
- if ((mangled && mangled_equal(name,name2))
- || fname_equal(name, name2))
- @@ -1709,8 +1710,7 @@
- ****************************************************************************/
- BOOL unbecome_user(void )
- {
- - if (ChDir(OriginalDir) != 0)
- - DEBUG(0,("%s chdir(%s) failed\n",timestring(),OriginalDir));
- + ChDir(OriginalDir);
-
- if (done_become_user == -1)
- return(False);
- @@ -1747,7 +1747,8 @@
- #endif
-
- if (ChDir(OriginalDir) != 0)
- - DEBUG(0,("%s chdir(%s) failed\n",timestring(),OriginalDir));
- + DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
- + timestring(),OriginalDir));
-
- DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
- getuid(),geteuid(),getgid(),getegid()));
- @@ -3143,7 +3144,7 @@
- standard_sub(cnum,fname);
- trim_string(fname,"","/");
-
- - if (!directory_exist(fname))
- + if (!directory_exist(fname,NULL))
- mkdir(fname,0755);
-
- strcat(fname,"/");
- @@ -3208,10 +3209,8 @@
- crec.uid = Connections[cnum].uid;
- crec.gid = Connections[cnum].gid;
- StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
- - {
- - time_t t = time(NULL);
- - crec.start = t + GMT_TO_LOCAL*TimeDiff(t);
- - }
- + crec.start = time(NULL);
- +
- {
- extern struct from_host Client_info;
- StrnCpy(crec.machine,Client_info.name,sizeof(crec.machine)-1);
- @@ -3744,7 +3743,7 @@
- uint32 a = interpret_addr("localhost");
- putip((void *)&ip,(void *)&a);
- *OutBuffer = 0;
- - send_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
- + send_one_packet(OutBuffer,1,&ip,137,SOCK_DGRAM);
- }
- #endif
-
- @@ -3963,6 +3962,8 @@
- #ifdef OSF1_ENH_SEC
- set_auth_parameters(argc,argv);
- #endif
- +
- + TimeInit();
-
- charset_initialise();
-
- diff -u -r --new-file last-version/source/smb.h samba-1.9.14p3/source/smb.h
- --- last-version/source/smb.h Sat Nov 4 22:13:27 1995
- +++ samba-1.9.14p3/source/smb.h Tue Nov 7 18:24:53 1995
- @@ -210,6 +210,7 @@
- int mode;
- int uid;
- int gid;
- + /* these times are normally kept in GMT */
- time_t mtime;
- time_t atime;
- time_t ctime;
- @@ -695,7 +696,7 @@
- void add_session_user(char *user);
- int valid_uid(int uid);
- user_struct *get_valid_user_struct(int uid);
- -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
- +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL nt_password);
- void register_uid(int uid,int gid,char *name,BOOL guest);
- BOOL fromhost(int sock,struct from_host *f);
- BOOL strhasupper(char *s);
- @@ -707,7 +708,7 @@
- BOOL check_file_sharing(int cnum,char *fname);
- char *StrCpy(char *dest,char *src);
- int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
- -time_t make_unix_date2(void *date_ptr,BOOL add_dst);
- +time_t make_unix_date2(void *date_ptr);
- int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
- mode_t unix_mode(int cnum,int dosmode);
- BOOL check_name(char *name,int cnum);
- @@ -724,7 +725,7 @@
- BOOL yield_connection(int cnum,char *name,int max_connections);
- int count_chars(char *s,char c);
- int smbrun(char *,char *);
- -BOOL name_convert(char *OutName,char *InName,BOOL need83,int snum);
- +BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
- struct hostent *Get_Hostbyname(char *name);
- struct passwd *Get_Pwnam(char *user,BOOL allow_change);
- void Abort(void);
- @@ -738,7 +739,9 @@
- void string_free(char **s);
- char *attrib_string(int mode);
- void unix_format(char *fname);
- -BOOL directory_exist(char *dname);
- +BOOL directory_exist(char *dname,struct stat *st);
- +time_t make_unix_date3(void *date_ptr);
- +void put_dos_date3(char *buf,int offset,time_t unixdate);
- void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
- BOOL in_list(char *s,char *list,BOOL case_sensitive);
- void strupper(char *s);
- @@ -767,7 +770,7 @@
- int dos_mode(int ,char *,struct stat *);
- char *timestring();
- BOOL ip_equal(struct in_addr *ip1,struct in_addr *ip2);
- -BOOL send_packet(char *buf,int len,struct in_addr *ip,int port,int type);
- +BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type);
- char *get_home_dir(char *);
- int set_filelen(int fd, long len);
- void put_dos_date(char *buf,int offset,time_t unixdate);
- @@ -776,7 +779,7 @@
- int name_len(char *s);
- void dos_clean_name(char *s);
- void unix_clean_name(char *s);
- -time_t make_unix_date(void *date_ptr,BOOL add_dst);
- +time_t make_unix_date(void *date_ptr);
- BOOL lanman2_match( char *str, char *regexp, int case_sig, BOOL autoext);
- BOOL trim_string(char *s,char *front,char *back);
- int byte_checksum(char *buf,int len);
- diff -u -r --new-file last-version/source/smbencrypt.c samba-1.9.14p3/source/smbencrypt.c
- --- last-version/source/smbencrypt.c Tue Jul 11 21:56:15 1995
- +++ samba-1.9.14p3/source/smbencrypt.c Sun Nov 5 15:46:54 1995
- @@ -24,12 +24,24 @@
- #include "includes.h"
- #include "loadparm.h"
- #include "des.h"
- +#include "md4.h"
-
- extern int DEBUGLEVEL;
-
- #ifndef uchar
- #define uchar unsigned char
- #endif
- +#ifndef int16
- +#define int16 unsigned short
- +#endif
- +#ifndef uint16
- +#define uint16 unsigned short
- +#endif
- +#ifndef uint32
- +#define uint32 unsigned int
- +#endif
- +
- +#include "byteorder.h"
-
- void str_to_key(uchar *str,uchar *key)
- {
- @@ -110,6 +122,81 @@
- E_P16(p14, p21);
- E_P24(p21, c8, p24);
- }
- +
- +/* Routines for Windows NT MD4 Hash functions. */
- +static int _my_wcslen(int16 *str)
- +{
- + int len = 0;
- + while(*str++ != 0)
- + len++;
- + return len;
- +}
- +
- +/*
- + * Convert a string into an NT UNICODE string.
- + * Note that regardless of processor type
- + * this must be in intel (little-endian)
- + * format.
- + */
- +
- +static int _my_mbstowcs(int16 *dst, uchar *src, int len)
- +{
- + int i;
- + int16 val;
- +
- + for(i = 0; i < len; i++) {
- + val = *src;
- + SSVAL(dst,0,val);
- + dst++;
- + src++;
- + if(val == 0)
- + break;
- + }
- + return i;
- +}
- +
- +/*
- + * Creates the MD4 Hash of the users password in NT UNICODE.
- + */
- +
- +void E_md4hash(uchar *passwd, uchar *p16)
- +{
- + int i, len;
- + int16 wpwd[129];
- + MDstruct MD;
- +
- + /* Password cannot be longer than 128 characters */
- + len = strlen(passwd);
- + if(len > 128)
- + len = 128;
- + /* Password must be converted to NT unicode */
- + _my_mbstowcs( wpwd, passwd, len);
- + wpwd[len] = 0; /* Ensure string is null terminated */
- + /* Calculate length in bytes */
- + len = _my_wcslen(wpwd) * sizeof(int16);
- +
- + MDbegin(&MD);
- + for(i = 0; i + 64 <= len; i += 64)
- + MDupdate(&MD,wpwd + (i/2), 512);
- + MDupdate(&MD,wpwd + (i/2),(len-i)*8);
- + SIVAL(p16,0,MD.buffer[0]);
- + SIVAL(p16,4,MD.buffer[1]);
- + SIVAL(p16,8,MD.buffer[2]);
- + SIVAL(p16,12,MD.buffer[3]);
- +}
- +
- +/* Does the NT MD4 hash then des encryption. */
- +
- +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
- +{
- + uchar p21[21];
- +
- + memset(p21,'\0',21);
- +
- + E_md4hash(passwd, p21);
- + E_P24(p21, c8, p24);
- +}
- +
- #else
- void smbencrypt_dummy(void){}
- #endif
- diff -u -r --new-file last-version/source/smbpass.c samba-1.9.14p3/source/smbpass.c
- --- last-version/source/smbpass.c Sun Sep 10 23:10:41 1995
- +++ samba-1.9.14p3/source/smbpass.c Mon Nov 6 16:54:57 1995
- @@ -1,281 +1,304 @@
- #ifdef SMB_PASSWD
- -/*
- - Unix SMB/Netbios implementation.
- - Version 1.9.
- - SMB parameters and setup
- - Copyright (C) Andrew Tridgell 1992-1995
- - Modified by Jeremy Allison 1995.
- -
- - This program is free software; you can redistribute it and/or modify
- - it under the terms of the GNU General Public License as published by
- - the Free Software Foundation; either version 2 of the License, or
- - (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU General Public License for more details.
- -
- - You should have received a copy of the GNU General Public License
- - along with this program; if not, write to the Free Software
- - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- -*/
- +/*
- + * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
- + * Copyright (C) Andrew Tridgell 1992-1995 Modified by Jeremy Allison 1995.
- + *
- + * This program is free software; you can redistribute it and/or modify it under
- + * the terms of the GNU General Public License as published by the Free
- + * Software Foundation; either version 2 of the License, or (at your option)
- + * any later version.
- + *
- + * This program is distributed in the hope that it will be useful, but WITHOUT
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + * more details.
- + *
- + * You should have received a copy of the GNU General Public License along with
- + * this program; if not, write to the Free Software Foundation, Inc., 675
- + * Mass Ave, Cambridge, MA 02139, USA.
- + */
-
- #include "includes.h"
- #include "loadparm.h"
-
- -extern int DEBUGLEVEL;
- +extern int DEBUGLEVEL;
-
- -int gotalarm;
- +int gotalarm;
-
- -void gotalarm_sig()
- +void
- +gotalarm_sig()
- {
- - gotalarm = 1;
- + gotalarm = 1;
- }
-
- -int do_pw_lock(int fd, int waitsecs, int type)
- +int
- +do_pw_lock(int fd, int waitsecs, int type)
- {
- - struct flock lock;
- - int ret;
- + struct flock lock;
- + int ret;
-
- - gotalarm = 0;
- + gotalarm = 0;
- signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-
- - lock.l_type = type;
- - lock.l_whence = SEEK_SET;
- - lock.l_start = 0;
- - lock.l_len = 1;
- - lock.l_pid = 0;
- -
- - alarm(5);
- - ret = fcntl(fd, F_SETLKW, &lock);
- - alarm(0);
- - signal( SIGALRM, SIGNAL_CAST SIG_DFL);
- -
- - if(gotalarm) {
- - DEBUG(0,("do_pw_lock: failed to %s SMB passwd file.\n",
- - type == F_UNLCK ? "unlock" : "lock" ));
- - return -1;
- - }
- - return ret;
- + lock.l_type = type;
- + lock.l_whence = SEEK_SET;
- + lock.l_start = 0;
- + lock.l_len = 1;
- + lock.l_pid = 0;
- +
- + alarm(5);
- + ret = fcntl(fd, F_SETLKW, &lock);
- + alarm(0);
- + signal(SIGALRM, SIGNAL_CAST SIG_DFL);
- +
- + if (gotalarm) {
- + DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
- + type == F_UNLCK ? "unlock" : "lock"));
- + return -1;
- + }
- + return ret;
- }
-
- -int pw_file_lock(const char *name, int type, int secs)
- +int
- +pw_file_lock(char *name, int type, int secs)
- {
- - int fd = open(name,O_RDWR|O_CREAT,0666);
- - if (fd < 0) return(-1);
- - if(do_pw_lock(fd, secs, type))
- - {
- + int fd = open(name, O_RDWR | O_CREAT, 0666);
- + if (fd < 0)
- + return (-1);
- + if (do_pw_lock(fd, secs, type)) {
- close(fd);
- return -1;
- - }
- + }
- return fd;
- }
-
- -int pw_file_unlock(int fd)
- +int
- +pw_file_unlock(int fd)
- {
- do_pw_lock(fd, 5, F_UNLCK);
- return close(fd);
- }
-
- /*
- - * Routine to search the smbpasswd file for an
- - * entry matching the username.
- + * Routine to get the next 32 hex characters and turn them
- + * into a 16 byte array.
- */
- -struct smb_passwd *get_smbpwnam(char *name)
- +
- +static int gethexpwd(char *p, char *pwd)
- {
- - /* Static buffers we will return. */
- - static struct smb_passwd pw_buf;
- - static pstring user_name;
- - static unsigned char smbpwd[16];
- - char linebuf[256];
- - char readbuf[16*1024];
- - unsigned char c;
- - unsigned char *p;
- - long uidval;
- - long linebuf_len;
- - unsigned char lonybble, hinybble;
- - int i;
- - FILE *fp;
- - int lockfd;
- - char *pfile = lp_smb_passwd_file();
- -
- - if (!*pfile) {
- - DEBUG(0,("No SMB password file set\n"));
- - return(NULL);
- - }
- -
- - DEBUG(10,("get_smbpwnam: opening file %s\n", pfile));
- -
- - fp = fopen(pfile,"r");
- -
- - if(fp == NULL)
- - {
- - DEBUG(0,("get_smbpwnam: unable to open file %s\n", pfile));
- - return NULL;
- - }
- -
- - /* Set a 16k buffer to do more efficient reads */
- - setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
- -
- - if((lockfd = pw_file_lock(pfile,F_RDLCK,5))<0) {
- - DEBUG(0,("get_smbpwnam: unable to lock file %s\n", pfile));
- - fclose(fp);
- - return NULL;
- - }
- -
- - /* make sure it is only rw by the owner */
- - chmod(pfile,0600);
- -
- - /* We have a read lock on the file. */
- - /* Scan the file, a line at a time and
- - check if the name matches. */
- - while(!feof(fp))
- - {
- - linebuf[0] = '\0';
- -
- - fgets(linebuf, 256, fp);
- - if(ferror(fp))
- - {
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- + int i;
- + unsigned char lonybble, hinybble;
- + char *hexchars = "0123456789ABCDEF";
- + char *p1, *p2;
- +
- + for (i = 0; i < 32; i += 2) {
- + hinybble = toupper(p[i]);
- + lonybble = toupper(p[i + 1]);
- +
- + p1 = strchr(hexchars, hinybble);
- + p2 = strchr(hexchars, lonybble);
- + if (!p1 || !p2)
- + return (False);
- + hinybble = PTR_DIFF(p1, hexchars);
- + lonybble = PTR_DIFF(p2, hexchars);
- +
- + pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- + return (True);
- +}
-
- - /* Check if the string is terminated with a newline -
- - if not then we must keep reading and discard until
- - we get one.
- - */
- - linebuf_len = strlen(linebuf);
- - if(linebuf[linebuf_len-1] != '\n')
- - {
- - c = '\0';
- - while(!ferror(fp) && !feof(fp))
- - {
- - c = fgetc(fp);
- - if(c == '\n')
- - break;
- - }
- +/*
- + * Routine to search the smbpasswd file for an entry matching the username.
- + */
- +struct smb_passwd *
- +get_smbpwnam(char *name)
- +{
- + /* Static buffers we will return. */
- + static struct smb_passwd pw_buf;
- + static pstring user_name;
- + static unsigned char smbpwd[16];
- + static unsigned char smbntpwd[16];
- + char linebuf[256];
- + char readbuf[16 * 1024];
- + unsigned char c;
- + unsigned char *p;
- + long uidval;
- + long linebuf_len;
- + FILE *fp;
- + int lockfd;
- + char *pfile = lp_smb_passwd_file();
- +
- + if (!*pfile) {
- + DEBUG(0, ("No SMB password file set\n"));
- + return (NULL);
- }
- - else
- - linebuf[linebuf_len-1] = '\0';
- + DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile));
-
- -#ifdef DEBUG_PASSWORD
- - DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
- -#endif
- - if((linebuf[0] == 0) && feof(fp))
- - {
- - DEBUG(4,("get_smbpwnam: end of file reached\n"));
- - break;
- - }
- - /* The line we have should be of the form :-
- -
- - username:uid:[32hex bytes]:....other flags presently ignored....
- -
- - */
- + fp = fopen(pfile, "r");
-
- - if(linebuf[0] == '#' || linebuf[0] == '\0')
- - {
- - DEBUG(6,("get_smbpwnam: skipping comment or blank line\n"));
- - continue;
- - }
- - p = (unsigned char *)strchr(linebuf, ':');
- - if( p == NULL)
- - {
- - DEBUG(0,("get_smbpwnam: malformed password entry (no :)\n"));
- - continue;
- + if (fp == NULL) {
- + DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile));
- + return NULL;
- }
- - /* As 256 is shorter than a pstring we don't
- - need to check length here - if this ever changes.... */
- - strncpy(user_name, linebuf, PTR_DIFF(p,linebuf));
- - user_name[PTR_DIFF(p,linebuf)] = '\0';
- - if(!strequal(user_name, name))
- - continue;
- -
- - /* User name matches - get uid and password */
- - p++; /* Go past ':' */
- - if(!isdigit(*p)) {
- - DEBUG(0,("get_smbpwnam: malformed password entry (uid not number)\n"));
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- - }
- + /* Set a 16k buffer to do more efficient reads */
- + setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- - uidval = atoi((char *)p);
- - while (*p && isdigit(*p)) p++;
- - if(*p != ':') {
- - DEBUG(0,("get_smbpwnam: malformed password entry (no : after uid)\n"));
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- - }
- + if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
- + DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile));
- + fclose(fp);
- + return NULL;
- + }
- + /* make sure it is only rw by the owner */
- + chmod(pfile, 0600);
-
- - /* Now get the password value - this should be 32 hex digits which
- - are the ascii representations of a 16 byte string. Get two at
- - a time and put them into the password.
- + /* We have a read lock on the file. */
- + /*
- + * Scan the file, a line at a time and check if the name matches.
- */
- - p++;
- - if(*p == '*' || *p == 'X') {
- - /* Password deliberately invalid - end here. */
- - DEBUG(10,("get_smbpwnam: entry invalidated for user %s\n",user_name));
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- - }
- - if(linebuf_len < (PTR_DIFF(p,linebuf) + 33)) {
- - DEBUG(0,("get_smbpwnam: malformed password entry (passwd too short)\n"));
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return(False);
- - }
- + while (!feof(fp)) {
- + linebuf[0] = '\0';
- +
- + fgets(linebuf, 256, fp);
- + if (ferror(fp)) {
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + /*
- + * Check if the string is terminated with a newline - if not
- + * then we must keep reading and discard until we get one.
- + */
- + linebuf_len = strlen(linebuf);
- + if (linebuf[linebuf_len - 1] != '\n') {
- + c = '\0';
- + while (!ferror(fp) && !feof(fp)) {
- + c = fgetc(fp);
- + if (c == '\n')
- + break;
- + }
- + } else
- + linebuf[linebuf_len - 1] = '\0';
- +
- +#ifdef DEBUG_PASSWORD
- + DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
- +#endif
- + if ((linebuf[0] == 0) && feof(fp)) {
- + DEBUG(4, ("get_smbpwnam: end of file reached\n"));
- + break;
- + }
- + /*
- + * The line we have should be of the form :-
- + *
- + * username:uid:[32hex bytes]:....other flags presently
- + * ignored....
- + *
- + * or,
- + *
- + * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- + *
- + * if Windows NT compatible passwords are also present.
- + */
- +
- + if (linebuf[0] == '#' || linebuf[0] == '\0') {
- + DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n"));
- + continue;
- + }
- + p = (unsigned char *) strchr(linebuf, ':');
- + if (p == NULL) {
- + DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n"));
- + continue;
- + }
- + /*
- + * As 256 is shorter than a pstring we don't need to check
- + * length here - if this ever changes....
- + */
- + strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- + user_name[PTR_DIFF(p, linebuf)] = '\0';
- + if (!strequal(user_name, name))
- + continue;
- +
- + /* User name matches - get uid and password */
- + p++; /* Go past ':' */
- + if (!isdigit(*p)) {
- + DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n"));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + uidval = atoi((char *) p);
- + while (*p && isdigit(*p))
- + p++;
- + if (*p != ':') {
- + DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n"));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + /*
- + * Now get the password value - this should be 32 hex digits
- + * which are the ascii representations of a 16 byte string.
- + * Get two at a time and put them into the password.
- + */
- + p++;
- + if (*p == '*' || *p == 'X') {
- + /* Password deliberately invalid - end here. */
- + DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
- + DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n"));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return (False);
- + }
- + if (p[32] != ':') {
- + DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n"));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
- + pw_buf.smb_passwd = NULL;
- + } else {
- + if(!gethexpwd(p,smbpwd)) {
- + DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + return NULL;
- + }
- + pw_buf.smb_passwd = smbpwd;
- + }
- + pw_buf.smb_name = user_name;
- + pw_buf.smb_userid = uidval;
- + pw_buf.smb_nt_passwd = NULL;
- +
- + /* Now check if the NT compatible password is
- + available. */
- + p += 33; /* Move to the first character of the line after
- + the lanman password. */
- + if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- + if (*p != '*' && *p != 'X') {
- + if(gethexpwd(p,smbntpwd))
- + pw_buf.smb_nt_passwd = smbntpwd;
- + }
- + }
- +
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
- + user_name, uidval));
- + return &pw_buf;
- + }
-
- - if(p[32] != ':') {
- - DEBUG(0,("get_smbpwnam: malformed password entry (no terminating :)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- - }
- -
- - if (!strncasecmp((char *)p,"NO PASSWORD", 11)) {
- - pw_buf.smb_passwd = NULL;
- - } else {
- - char *hexchars = "0123456789ABCDEF";
- - char *p1,*p2;
- - for(i = 0; i < 32; i += 2)
- - {
- - hinybble = toupper(p[i]);
- - lonybble = toupper(p[i+1]);
- -
- - p1 = strchr(hexchars,hinybble);
- - p2 = strchr(hexchars,lonybble);
- - if (!p1 || !p2) {
- - DEBUG(0,("Malformed password entry (non hex chars)\n"));
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- - }
- -
- - hinybble = PTR_DIFF(p1,hexchars);
- - lonybble = PTR_DIFF(p2,hexchars);
- -
- - smbpwd[i/2] = (hinybble << 4) | lonybble;
- - }
- - pw_buf.smb_passwd = smbpwd;
- - }
- - pw_buf.smb_name = user_name;
- - pw_buf.smb_userid = uidval;
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - DEBUG(5,("get_smbpwname: returning passwd entry for user %s, uid %d\n",
- - user_name, uidval));
- - return &pw_buf;
- - }
- -
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - return NULL;
- }
- #else
- -void smbpass_dummy(void){} /* To avoid compiler complaints */
- +void
- +smbpass_dummy(void)
- +{
- +} /* To avoid compiler complaints */
- #endif
- -
- diff -u -r --new-file last-version/source/smbpass.h samba-1.9.14p3/source/smbpass.h
- --- last-version/source/smbpass.h Sun Sep 10 23:10:47 1995
- +++ samba-1.9.14p3/source/smbpass.h Mon Nov 6 16:54:56 1995
- @@ -25,6 +25,7 @@
- int smb_userid;
- char *smb_name;
- unsigned char *smb_passwd; /* Null if no password */
- + unsigned char *smb_nt_passwd; /* Null if no password */
- /* Other fields / flags may be added later */
- };
-
- @@ -39,9 +40,11 @@
- void str_to_key(unsigned char *str,unsigned char *key);
- void E_P16(uchar *p14,uchar *p16);
- void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
- +void E_md4hash(uchar *passwd,uchar *p16);
- void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
- +void SMB_nt_encrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
-
- /* Password file lock/unlock routines */
- -int pw_file_lock(const char *name, int type, int secs);
- +int pw_file_lock(char *name, int type, int secs);
- int pw_file_unlock(int fd);
- #endif
- diff -u -r --new-file last-version/source/smbpasswd.c samba-1.9.14p3/source/smbpasswd.c
- --- last-version/source/smbpasswd.c Sun Sep 10 23:28:28 1995
- +++ samba-1.9.14p3/source/smbpasswd.c Mon Nov 6 16:54:38 1995
- @@ -1,381 +1,447 @@
- #ifdef SMB_PASSWD
-
- -/*
- - Unix SMB/Netbios implementation.
- - Version 1.9.
- - smbpasswd module.
- - Copyright (C) Jeremy Allison 1995.
- -
- - This program is free software; you can redistribute it and/or modify
- - it under the terms of the GNU General Public License as published by
- - the Free Software Foundation; either version 2 of the License, or
- - (at your option) any later version.
- -
- - This program is distributed in the hope that it will be useful,
- - but WITHOUT ANY WARRANTY; without even the implied warranty of
- - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- - GNU General Public License for more details.
- -
- - You should have received a copy of the GNU General Public License
- - along with this program; if not, write to the Free Software
- - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- -*/
- +/*
- + * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- + * (C) Jeremy Allison 1995.
- + *
- + * This program is free software; you can redistribute it and/or modify it under
- + * the terms of the GNU General Public License as published by the Free
- + * Software Foundation; either version 2 of the License, or (at your option)
- + * any later version.
- + *
- + * This program is distributed in the hope that it will be useful, but WITHOUT
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + * more details.
- + *
- + * You should have received a copy of the GNU General Public License along with
- + * this program; if not, write to the Free Software Foundation, Inc., 675
- + * Mass Ave, Cambridge, MA 02139, USA.
- + */
-
- #include "includes.h"
- #include "des.h"
-
- #ifdef SMBGETPASS
- -extern char *getsmbpass(const char *);
- +extern char *getsmbpass(char *);
- #define getpass getsmbpass
- #endif
-
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- -static pstring user_name;
- +static pstring user_name;
- static unsigned char smbpwd[16];
- +static unsigned char smbntpwd[16];
-
- -struct smb_passwd *_my_get_smbpwnam(FILE *fp,char *name, BOOL *valid_old_pwd, long *pwd_seekpos)
- +static int gethexpwd(char *p, char *pwd)
- {
- - char linebuf[256];
- - unsigned char c;
- - unsigned char *p;
- - long uidval;
- - long linebuf_len;
- - unsigned char lonybble, hinybble;
- - int i;
- -
- - /* Scan the file, a line at a time and
- - check if the name matches. */
- - while(!feof(fp))
- - {
- - linebuf[0] = '\0';
- - *pwd_seekpos = ftell(fp);
- + int i;
- + unsigned char lonybble, hinybble;
- + char *hexchars = "0123456789ABCDEF";
- + char *p1, *p2;
- + for (i = 0; i < 32; i += 2) {
- + hinybble = toupper(p[i]);
- + lonybble = toupper(p[i + 1]);
- +
- + p1 = strchr(hexchars, hinybble);
- + p2 = strchr(hexchars, lonybble);
- + if (!p1 || !p2)
- + return (False);
-
- - fgets(linebuf, 256, fp);
- - if(ferror(fp))
- - return NULL;
- + hinybble = PTR_DIFF(p1, hexchars);
- + lonybble = PTR_DIFF(p2, hexchars);
-
- - /* Check if the string is terminated with a newline -
- - if not then we must keep reading and discard until
- - we get one.
- - */
- - linebuf_len = strlen(linebuf);
- - if(linebuf[linebuf_len-1] != '\n')
- - {
- - c = '\0';
- - while(!ferror(fp) && !feof(fp))
- - {
- - c = fgetc(fp);
- - if(c == '\n')
- - break;
- - }
- - }
- - else
- - linebuf[linebuf_len-1] = '\0';
- -
- - if((linebuf[0] == 0) && feof(fp))
- - break;
- - /* The line we have should be of the form :-
- + pwd[i / 2] = (hinybble << 4) | lonybble;
- + }
- + return (True);
- +}
-
- - username:uid:[32hex bytes]:....other flags presently ignored....
- - */
- +struct smb_passwd *
- +_my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
- + BOOL *got_valid_nt_entry, long *pwd_seekpos)
- +{
- + char linebuf[256];
- + unsigned char c;
- + unsigned char *p;
- + long uidval;
- + long linebuf_len;
-
- - if(linebuf[0] == '#' || linebuf[0] == '\0')
- - continue;
- - p = (unsigned char *)strchr(linebuf, ':');
- - if( p == NULL)
- - continue;
- - /* As 256 is shorter than a pstring we don't
- - need to check length here - if this ever changes.... */
- - strncpy( user_name, linebuf, PTR_DIFF(p,linebuf));
- - user_name[PTR_DIFF(p,linebuf)] = '\0';
- - if(!strequal(user_name, name))
- - continue;
- -
- - /* User name matches - get uid and password */
- - p++; /* Go past ':' */
- - if(!isdigit(*p))
- - return(False);
- -
- - uidval = atoi((char *)p);
- - while (*p && isdigit(*p)) p++;
- -
- - if(*p != ':')
- - return(False);
- -
- - /* Now get the password value - this should be 32 hex digits which
- - are the ascii representations of a 16 byte string. Get two at
- - a time and put them into the password.
- + /*
- + * Scan the file, a line at a time and check if the name matches.
- */
- - p++;
- - *pwd_seekpos += PTR_DIFF(p,linebuf); /* Save exact position of
- - passwd in file - this is used
- - by smbpasswd.c
- - */
- - if(*p == '*' || *p == 'X')
- - {
- - /* Password deliberately invalid - end here. */
- - *valid_old_pwd = False;
- - pw_buf.smb_name = user_name;
- - pw_buf.smb_userid = uidval;
- - return(&pw_buf);
- - }
- - if(linebuf_len < (PTR_DIFF(p,linebuf) + 33))
- - return(False);
- -
- - if(p[32] != ':')
- - return(False);
- -
- - if(!strncasecmp(p,"NO PASSWORD",11)) {
- - pw_buf.smb_passwd = NULL; /* No password */
- - } else {
- - char *hexchars = "0123456789ABCDEF";
- - char *p1,*p2;
- - for(i = 0; i < 32; i += 2)
- - {
- - hinybble = toupper(p[i]);
- - lonybble = toupper(p[i+1]);
- -
- - p1 = strchr(hexchars,hinybble);
- - p2 = strchr(hexchars,lonybble);
- - if (!p1 || !p2)
- - return(False);
- -
- - hinybble = PTR_DIFF(p1,hexchars);
- - lonybble = PTR_DIFF(p2,hexchars);
- -
- - smbpwd[i/2] = (hinybble << 4) | lonybble;
- - }
- - pw_buf.smb_passwd = smbpwd;
- - }
- -
- - pw_buf.smb_name = user_name;
- - pw_buf.smb_userid = uidval;
- - *valid_old_pwd = True;
- - return &pw_buf;
- - }
- - return NULL;
- + while (!feof(fp)) {
- + linebuf[0] = '\0';
- + *pwd_seekpos = ftell(fp);
- +
- + fgets(linebuf, 256, fp);
- + if (ferror(fp))
- + return NULL;
- +
- + /*
- + * Check if the string is terminated with a newline - if not
- + * then we must keep reading and discard until we get one.
- + */
- + linebuf_len = strlen(linebuf);
- + if (linebuf[linebuf_len - 1] != '\n') {
- + c = '\0';
- + while (!ferror(fp) && !feof(fp)) {
- + c = fgetc(fp);
- + if (c == '\n')
- + break;
- + }
- + } else
- + linebuf[linebuf_len - 1] = '\0';
- +
- + if ((linebuf[0] == 0) && feof(fp))
- + break;
- + /*
- + * The line we have should be of the form :-
- + *
- + * username:uid:[32hex bytes]:....other flags presently
- + * ignored....
- + *
- + * or,
- + *
- + * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- + *
- + * if Windows NT compatible passwords are also present.
- + */
- +
- + if (linebuf[0] == '#' || linebuf[0] == '\0')
- + continue;
- + p = (unsigned char *) strchr(linebuf, ':');
- + if (p == NULL)
- + continue;
- + /*
- + * As 256 is shorter than a pstring we don't need to check
- + * length here - if this ever changes....
- + */
- + strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- + user_name[PTR_DIFF(p, linebuf)] = '\0';
- + if (!strequal(user_name, name))
- + continue;
- +
- + /* User name matches - get uid and password */
- + p++; /* Go past ':' */
- + if (!isdigit(*p))
- + return (False);
- +
- + uidval = atoi((char *) p);
- + while (*p && isdigit(*p))
- + p++;
- +
- + if (*p != ':')
- + return (False);
- +
- + /*
- + * Now get the password value - this should be 32 hex digits
- + * which are the ascii representations of a 16 byte string.
- + * Get two at a time and put them into the password.
- + */
- + p++;
- + *pwd_seekpos += PTR_DIFF(p, linebuf); /* Save exact position
- + * of passwd in file -
- + * this is used by
- + * smbpasswd.c */
- + if (*p == '*' || *p == 'X') {
- + /* Password deliberately invalid - end here. */
- + *valid_old_pwd = False;
- + *got_valid_nt_entry = False;
- + pw_buf.smb_name = user_name;
- + pw_buf.smb_userid = uidval;
- + pw_buf.smb_passwd = NULL; /* No password */
- + pw_buf.smb_nt_passwd = NULL; /* No password */
- + return (&pw_buf);
- + }
- + if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- + return (False);
- +
- + if (p[32] != ':')
- + return (False);
- +
- + if (!strncasecmp(p, "NO PASSWORD", 11)) {
- + pw_buf.smb_passwd = NULL; /* No password */
- + } else {
- + if(!gethexpwd(p,smbpwd))
- + return False;
- + pw_buf.smb_passwd = smbpwd;
- + }
- +
- + pw_buf.smb_name = user_name;
- + pw_buf.smb_userid = uidval;
- + pw_buf.smb_nt_passwd = NULL;
- + *got_valid_nt_entry = False;
- + *valid_old_pwd = True;
- +
- + /* Now check if the NT compatible password is
- + available. */
- + p += 33; /* Move to the first character of the line after
- + the lanman password. */
- + if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- + /* NT Entry was valid - even if 'X' or '*', can be overwritten */
- + *got_valid_nt_entry = True;
- + if (*p != '*' && *p != 'X') {
- + if(gethexpwd(p,smbntpwd))
- + pw_buf.smb_nt_passwd = smbntpwd;
- + }
- + }
- + return &pw_buf;
- + }
- + return NULL;
- }
-
- /*
- * Print command usage on stderr and die.
- */
- -void usage(char *name)
- +void
- +usage(char *name)
- {
- fprintf(stderr, "Usage is : %s [username]\n", name);
- exit(1);
- }
-
- -int main(int argc, char **argv)
- +int
- +main(int argc, char **argv)
- {
- - int real_uid;
- - struct passwd *pwd;
- - fstring old_passwd;
- - uchar old_p16[16];
- - fstring new_passwd;
- - uchar new_p16[16];
- - char *p;
- - struct smb_passwd *smb_pwent;
- - FILE *fp;
- - BOOL valid_old_pwd = False;
- - long seekpos;
- - int pwfd;
- - char ascii_p16[33];
- - char c;
- - int ret, i, err;
- - int lockfd=-1;
- - char *pfile = SMB_PASSWD_FILE;
- - char readbuf[16*1024];
- + int real_uid;
- + struct passwd *pwd;
- + fstring old_passwd;
- + uchar old_p16[16];
- + uchar old_nt_p16[16];
- + fstring new_passwd;
- + uchar new_p16[16];
- + uchar new_nt_p16[16];
- + char *p;
- + struct smb_passwd *smb_pwent;
- + FILE *fp;
- + BOOL valid_old_pwd = False;
- + BOOL got_valid_nt_entry = False;
- + long seekpos;
- + int pwfd;
- + char ascii_p16[66];
- + char c;
- + int ret, i, err, writelen;
- + int lockfd = -1;
- + char *pfile = SMB_PASSWD_FILE;
- + char readbuf[16 * 1024];
-
- - charset_initialise();
- + charset_initialise();
-
- #ifndef DEBUG_PASSWORD
- - /* Check the effective uid */
- - if(geteuid() != 0) {
- - fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
- - exit(1);
- - }
- + /* Check the effective uid */
- + if (geteuid() != 0) {
- + fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
- + exit(1);
- + }
- #endif
-
- - /* Get the real uid */
- - real_uid = getuid();
- -
- - /* Deal with usage problems */
- - if( real_uid == 0) {
- - /* As root we can change anothers password. */
- - if(argc != 1 && argc != 2)
- - usage(argv[0]);
- - } else if(argc != 1)
- - usage(argv[0]);
- -
- -
- - if(real_uid == 0 && argc == 2) {
- - /* If we are root we can change anothers password. */
- - strncpy( user_name, argv[1], sizeof(user_name)-1);
- - user_name[sizeof(user_name)-1] = '\0';
- - pwd = getpwnam( user_name );
- - } else {
- - pwd = getpwuid( real_uid );
- - }
- -
- - if(pwd == 0) {
- - fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
- - exit(1);
- - }
- -
- - /* If we are root we don't ask for the old password. */
- - old_passwd[0] = '\0';
- - if(real_uid != 0) {
- - p = getpass("Old SMB password:");
- - strncpy(old_passwd, p, 14);
- - old_passwd[14] = '\0';
- - strupper(old_passwd);
- - }
- -
- - new_passwd[0] = '\0';
- - p = getpass("New SMB password:");
- - strncpy(new_passwd, p, 14);
- - new_passwd[14] = '\0';
- - p = getpass("Retype new SMB password:");
- - if(strncmp(p, new_passwd, 14)) {
- - fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
- - exit(1);
- - }
- - strupper(new_passwd);
- -
- - if(new_passwd[0] == '\0') {
- - printf("Password not set\n");
- - exit(0);
- - }
- -
- - /* Calculate the SMB hash functions of
- - both old an new passwords. */
- -
- - memset(old_p16,'\0',16);
- - E_P16((uchar *)old_passwd,old_p16);
- -
- - memset(new_p16,'\0',16);
- - E_P16((uchar *)new_passwd,new_p16);
- -
- - /* Open the smbpaswd file XXXX - we need to parse smb.conf to
- - get the filename */
- - if((fp = fopen(pfile, "r+")) == NULL) {
- - err = errno;
- - fprintf(stderr, "%s: Failed to open password file %s.\n",
- - argv[0], pfile);
- - errno = err;
- - perror(argv[0]);
- - exit(err);
- - }
- -
- - /* Set read buffer to 16k for effiecient reads */
- - setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
- -
- - /* make sure it is only rw by the owner */
- - chmod(pfile,0600);
- -
- - /* Lock the smbpasswd file for write. */
- - if((lockfd=pw_file_lock(pfile,F_WRLCK,5))<0) {
- - err = errno;
- - fprintf(stderr, "%s: Failed to lock password file %s.\n",
- - argv[0], pfile);
- - fclose(fp);
- - errno = err;
- - perror(argv[0]);
- - exit(err);
- - }
- -
- - /* Get the smb passwd entry for this user */
- - smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd, &seekpos);
- - if(smb_pwent == NULL) {
- - fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
- - argv[0], pwd->pw_name, pfile);
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - exit(1);
- - }
- -
- - /* If we are root we don't need to check the old password. */
- - if( real_uid != 0) {
- - if( valid_old_pwd == False) {
- - fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - exit(1);
- + /* Get the real uid */
- + real_uid = getuid();
- +
- + /* Deal with usage problems */
- + if (real_uid == 0) {
- + /* As root we can change anothers password. */
- + if (argc != 1 && argc != 2)
- + usage(argv[0]);
- + } else if (argc != 1)
- + usage(argv[0]);
- +
- +
- + if (real_uid == 0 && argc == 2) {
- + /* If we are root we can change anothers password. */
- + strncpy(user_name, argv[1], sizeof(user_name) - 1);
- + user_name[sizeof(user_name) - 1] = '\0';
- + pwd = getpwnam(user_name);
- + } else {
- + pwd = getpwuid(real_uid);
- + }
- +
- + if (pwd == 0) {
- + fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
- + exit(1);
- + }
- + /* If we are root we don't ask for the old password. */
- + old_passwd[0] = '\0';
- + if (real_uid != 0) {
- + p = getpass("Old SMB password:");
- + strncpy(old_passwd, p, sizeof(fstring));
- + old_passwd[sizeof(fstring)-1] = '\0';
- + }
- + new_passwd[0] = '\0';
- + p = getpass("New SMB password:");
- + strncpy(new_passwd, p, sizeof(fstring));
- + new_passwd[sizeof(fstring)-1] = '\0';
- + p = getpass("Retype new SMB password:");
- + if (strcmp(p, new_passwd)) {
- + fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
- + exit(1);
- + }
- +
- + if (new_passwd[0] == '\0') {
- + printf("Password not set\n");
- + exit(0);
- + }
- +
- + /* Calculate the MD4 hash (NT compatible) of the old and new passwords */
- + memset(old_nt_p16, '\0', 16);
- + E_md4hash((uchar *)old_passwd, old_nt_p16);
- +
- + memset(new_nt_p16, '\0', 16);
- + E_md4hash((uchar *) new_passwd, new_nt_p16);
- +
- + /* Mangle the passwords into Lanman format */
- + old_passwd[14] = '\0';
- + strupper(old_passwd);
- + new_passwd[14] = '\0';
- + strupper(new_passwd);
- +
- + /*
- + * Calculate the SMB (lanman) hash functions of both old and new passwords.
- + */
- +
- + memset(old_p16, '\0', 16);
- + E_P16((uchar *) old_passwd, old_p16);
- +
- + memset(new_p16, '\0', 16);
- + E_P16((uchar *) new_passwd, new_p16);
- +
- + /*
- + * Open the smbpaswd file XXXX - we need to parse smb.conf to get the
- + * filename
- + */
- + if ((fp = fopen(pfile, "r+")) == NULL) {
- + err = errno;
- + fprintf(stderr, "%s: Failed to open password file %s.\n",
- + argv[0], pfile);
- + errno = err;
- + perror(argv[0]);
- + exit(err);
- + }
- + /* Set read buffer to 16k for effiecient reads */
- + setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
- +
- + /* make sure it is only rw by the owner */
- + chmod(pfile, 0600);
- +
- + /* Lock the smbpasswd file for write. */
- + if ((lockfd = pw_file_lock(pfile, F_WRLCK, 5)) < 0) {
- + err = errno;
- + fprintf(stderr, "%s: Failed to lock password file %s.\n",
- + argv[0], pfile);
- + fclose(fp);
- + errno = err;
- + perror(argv[0]);
- + exit(err);
- + }
- + /* Get the smb passwd entry for this user */
- + smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd,
- + &got_valid_nt_entry, &seekpos);
- + if (smb_pwent == NULL) {
- + fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
- + argv[0], pwd->pw_name, pfile);
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + /* If we are root we don't need to check the old password. */
- + if (real_uid != 0) {
- + if ((valid_old_pwd == False) || (smb_pwent->smb_passwd == NULL)) {
- + fprintf(stderr, "%s: User %s is disabled, plase contact your administrator to enable it.\n", argv[0], pwd->pw_name);
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + /* Check the old Lanman password */
- + if (memcmp(old_p16, smb_pwent->smb_passwd, 16)) {
- + fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + /* Check the NT password if it exists */
- + if (smb_pwent->smb_nt_passwd != NULL) {
- + if (memcmp(old_nt_p16, smb_pwent->smb_nt_passwd, 16)) {
- + fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + }
- + }
- + /*
- + * If we get here either we were root or the old password checked out
- + * ok.
- + */
- + /* Create the 32 byte representation of the new p16 */
- + for (i = 0; i < 16; i++) {
- + sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]);
- + }
- + if(got_valid_nt_entry) {
- + /* Add on the NT md4 hash */
- + ascii_p16[32] = ':';
- + for (i = 0; i < 16; i++) {
- + sprintf(&ascii_p16[(i * 2)+33], "%02X", (uchar) new_nt_p16[i]);
- + }
- }
- - /* Check the old passwd (if there was one). */
- - if(smb_pwent->smb_passwd != NULL) {
- - if( memcmp( old_p16, smb_pwent->smb_passwd, 16)) {
- - fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- + /*
- + * Do an atomic write into the file at the position defined by
- + * seekpos.
- + */
- + pwfd = fileno(fp);
- + ret = lseek(pwfd, seekpos - 1, SEEK_SET);
- + if (ret != seekpos - 1) {
- + err = errno;
- + fprintf(stderr, "%s: seek fail on file %s.\n",
- + argv[0], pfile);
- + fclose(fp);
- + errno = err;
- + perror(argv[0]);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + /* Sanity check - ensure the character is a ':' */
- + if (read(pwfd, &c, 1) != 1) {
- + err = errno;
- + fprintf(stderr, "%s: read fail on file %s.\n",
- + argv[0], pfile);
- + fclose(fp);
- + errno = err;
- + perror(argv[0]);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + if (c != ':') {
- + fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
- + argv[0], pfile);
- + fclose(fp);
- + pw_file_unlock(lockfd);
- + exit(1);
- + }
- + writelen = (got_valid_nt_entry) ? 65 : 32;
- + if (write(pwfd, ascii_p16, writelen) != writelen) {
- + err = errno;
- + fprintf(stderr, "%s: write fail in file %s.\n",
- + argv[0], pfile);
- + fclose(fp);
- + errno = err;
- + perror(argv[0]);
- + pw_file_unlock(lockfd);
- + exit(err);
- + }
- fclose(fp);
- pw_file_unlock(lockfd);
- - exit(1);
- - }
- - }
- - }
- - /* If we get here either we were root or the old password
- - checked out ok. */
- - /* Create the 32 byte representation of the new p16 */
- - for(i = 0; i < 16; i++) {
- - sprintf(&ascii_p16[i*2], "%02X", (uchar)new_p16[i]);
- - }
- - /* Do an atomic write into the file at the position
- - defined by seekpos. */
- - pwfd = fileno(fp);
- - ret = lseek(pwfd, seekpos - 1, SEEK_SET);
- - if(ret != seekpos -1) {
- - err = errno;
- - fprintf(stderr, "%s: seek fail on file %s.\n",
- - argv[0], pfile);
- - fclose(fp);
- - errno = err;
- - perror(argv[0]);
- - pw_file_unlock(lockfd);
- - exit(1);
- - }
- - /* Sanity check - ensure the character is a ':' */
- - if(read(pwfd,&c,1) != 1) {
- - err = errno;
- - fprintf(stderr, "%s: read fail on file %s.\n",
- - argv[0], pfile);
- - fclose(fp);
- - errno = err;
- - perror(argv[0]);
- - pw_file_unlock(lockfd);
- - exit(1);
- - }
- - if(c != ':') {
- - fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
- - argv[0], pfile);
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - exit(1);
- - }
- - if(write(pwfd,ascii_p16,32)!=32) {
- - err = errno;
- - fprintf(stderr, "%s: write fail in file %s.\n",
- - argv[0], pfile);
- - fclose(fp);
- - errno = err;
- - perror(argv[0]);
- - pw_file_unlock(lockfd);
- - exit(err);
- - }
- - fclose(fp);
- - pw_file_unlock(lockfd);
- - printf("Password changed\n");
- - return 0;
- + printf("Password changed\n");
- + return 0;
- }
-
- #else
-
- #include "includes.h"
-
- -int main(int argc, char **argv)
- +int
- +main(int argc, char **argv)
- {
- - printf("smb password encryption not selected in Makefile\n");
- - return 0;
- + printf("smb password encryption not selected in Makefile\n");
- + return 0;
- }
- #endif
- -
- -
- diff -u -r --new-file last-version/source/status.c samba-1.9.14p3/source/status.c
- --- last-version/source/status.c Sat Nov 4 23:19:07 1995
- +++ samba-1.9.14p3/source/status.c Mon Nov 6 15:55:40 1995
- @@ -117,7 +117,8 @@
- else
- printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s",
- crec.name,uidtoname(crec.uid),gidtoname(crec.gid),crec.pid,
- - crec.machine,crec.addr,asctime(LocalTime(&crec.start,0)));
- + crec.machine,crec.addr,
- + asctime(LocalTime(&crec.start,GMT_TO_LOCAL)));
- }
- }
- fclose(f);
- diff -u -r --new-file last-version/source/trans2.c samba-1.9.14p3/source/trans2.c
- --- last-version/source/trans2.c Sat Nov 4 20:29:20 1995
- +++ samba-1.9.14p3/source/trans2.c Tue Nov 7 13:59:36 1995
- @@ -163,7 +163,7 @@
- #if 0
- BOOL return_additional_info = BITSETW(params,0);
- int16 open_sattr = SVAL(params, 4);
- - int32 open_time = IVAL(params,8);
- + time_t open_time = make_unix_date3(params+8);
- #endif
- int16 open_ofun = SVAL(params,12);
- int32 open_size = IVAL(params,14);
- @@ -348,7 +348,6 @@
-
- #ifdef MANGLE_LONG_FILENAMES
- {
- - fstring fname2;
- BOOL illegal = False;
- int i;
- int l = strlen(fname);
- @@ -357,8 +356,7 @@
- illegal = True;
- break;
- }
- - name_convert(fname2,fname,illegal,SNUM(cnum));
- - strcpy(fname,fname2);
- + name_map_mangle(fname,illegal,SNUM(cnum));
- }
- #endif
-
- @@ -445,13 +443,15 @@
- SIVAL(p,0,mode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- SIVAL(p,0,0); p += 4;
- - if (!is_8_3(fname))
- - name_convert(p+2,fname,True,SNUM(cnum));
- - else
- + if (!is_8_3(fname)) {
- + strcpy(p+2,unix2dos_format(fname,False));
- + name_map_mangle(p+2,True,SNUM(cnum));
- + } else
- *(p+2) = 0;
- strupper(p+2);
- SSVAL(p,0,strlen(p+2));
- p += 2 + 24;
- + /* name_ptr = p; */
- strcpy(p,fname); p += strlen(p);
- break;
-
- @@ -1208,8 +1208,8 @@
- switch (info_level)
- {
- case 1:
- - tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess,False);
- - tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite,False);
- + tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
- + tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
- mode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
- break;
- @@ -1217,15 +1217,15 @@
- case 2:
- if(IVAL(pdata,l2_cbList) || total_data>32)
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
- - tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess,False);
- - tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite,False);
- + tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
- + tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
- mode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
- break;
-
- case 3:
- - tvs.actime = make_unix_date2(pdata+8,False);
- - tvs.modtime = make_unix_date2(pdata+12,False);
- + tvs.actime = make_unix_date2(pdata+8);
- + tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
- @@ -1233,8 +1233,8 @@
- case 4:
- if (IVAL(pdata,28) != 0 || total_data>36)
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
- - tvs.actime = make_unix_date2(pdata+8,False);
- - tvs.modtime = make_unix_date2(pdata+12,False);
- + tvs.actime = make_unix_date2(pdata+8);
- + tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
- diff -u -r --new-file last-version/source/updatesmbpasswd.sh samba-1.9.14p3/source/updatesmbpasswd.sh
- --- last-version/source/updatesmbpasswd.sh Thu Jan 1 10:00:00 1970
- +++ samba-1.9.14p3/source/updatesmbpasswd.sh Sun Nov 5 15:47:33 1995
- @@ -0,0 +1,14 @@
- +#!/bin/sh
- +nawk 'BEGIN {FS=":"}
- +{
- + if( $0 ~ "^#" ) {
- + print $0
- + } else if( (length($4) == 32) && (($4 ~ "^[0-9A-F]*$") || ($4 ~ "^[X]*$") || ( $4 ~ "^[*]*$"))) {
- + print $0
- + } else {
- + printf( "%s:%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", $1, $2, $3);
- + for(i = 4; i <= NF; i++)
- + printf("%s:", $i)
- + printf("\n")
- + }
- +}'
- diff -u -r --new-file last-version/source/util.c samba-1.9.14p3/source/util.c
- --- last-version/source/util.c Sat Nov 4 22:14:20 1995
- +++ samba-1.9.14p3/source/util.c Tue Nov 7 18:24:45 1995
- @@ -288,6 +288,11 @@
- tm_local = *(localtime(&t));
-
- timediff = mktime(&tm_utc) - mktime(&tm_local);
- +
- + if (serverzone == 0) {
- + serverzone = timediff - DSTDiff(t);
- + DEBUG(4,("Serverzone is %d\n",serverzone));
- + }
- }
-
-
- @@ -365,20 +370,10 @@
- int TimeDiff(time_t t)
- {
- static BOOL initialised = False;
- - if (!initialised) {TimeInit(); initialised=True;}
- + if (!initialised) {initialised=True; TimeInit();}
- return(timediff - DSTDiff(t));
- }
-
- -
- -/****************************************************************************
- -try to optimise the timelocal call, it can be quite expenive on some machines
- -****************************************************************************/
- -static time_t TimeLocal(struct tm *tm,int timemul)
- -{
- - time_t ret = mktime(tm);
- - return(ret + timemul * TimeDiff(ret));
- -}
- -
- /****************************************************************************
- try to optimise the localtime call, it can be quite expenive on some machines
- timemul is normally LOCAL_TO_GMT, GMT_TO_LOCAL or 0
- @@ -387,7 +382,8 @@
- {
- time_t t2 = *t;
-
- - t2 += timemul * TimeDiff(t2);
- + if (timemul)
- + t2 += timemul * TimeDiff(t2);
-
- return(gmtime(&t2));
- }
- @@ -680,6 +676,15 @@
- char *StrCpy(char *dest,char *src)
- {
- char *d = dest;
- +
- +#if AJT
- + /* I don't want to get lazy with these ... */
- + if (!dest || !src) {
- + DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
- + ajt_panic();
- + }
- +#endif
- +
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- @@ -830,14 +835,15 @@
- /*******************************************************************
- check if a directory exists
- ********************************************************************/
- -BOOL directory_exist(char *dname)
- +BOOL directory_exist(char *dname,struct stat *st)
- {
- - struct stat st;
- + struct stat st2;
- + if (!st) st = &st2;
-
- - if (sys_stat(dname,&st) != 0)
- + if (sys_stat(dname,st) != 0)
- return(False);
-
- - return(S_ISDIR(st.st_mode));
- + return(S_ISDIR(st->st_mode));
- }
-
- /*******************************************************************
- @@ -851,6 +857,16 @@
- return(buf.st_size);
- }
-
- +/****************************************************************************
- +check if it's a null mtime
- +****************************************************************************/
- +static BOOL null_mtime(time_t mtime)
- +{
- + if (mtime == 0 || mtime == 0xFFFFFFFF)
- + return(True);
- + return(False);
- +}
- +
- /*******************************************************************
- create a 16 bit dos packed date
- ********************************************************************/
- @@ -875,6 +891,7 @@
-
- /*******************************************************************
- create a 32 bit dos packed date/time from some parameters
- + This takes a GMT time and returns a packed localtime structure
- ********************************************************************/
- static uint32 make_dos_date(time_t unixdate)
- {
- @@ -891,6 +908,7 @@
-
- /*******************************************************************
- put a dos date into a buffer (time/date format)
- +This takes GMT time and puts local time in the buffer
- ********************************************************************/
- void put_dos_date(char *buf,int offset,time_t unixdate)
- {
- @@ -900,6 +918,7 @@
-
- /*******************************************************************
- put a dos date into a buffer (date/time format)
- +This takes GMT time and puts local time in the buffer
- ********************************************************************/
- void put_dos_date2(char *buf,int offset,time_t unixdate)
- {
- @@ -908,6 +927,17 @@
- SIVAL(buf,offset,x);
- }
-
- +/*******************************************************************
- +put a dos 32 bit "unix like" date into a buffer. This routine takes
- +GMT and converts it to LOCAL time before putting it (most SMBs assume
- +localtime for this sort of date)
- +********************************************************************/
- +void put_dos_date3(char *buf,int offset,time_t unixdate)
- +{
- + if (!null_mtime(unixdate))
- + unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
- + SIVAL(buf,offset,unixdate);
- +}
-
- /*******************************************************************
- interpret a 32 bit dos packed date/time to some parameters
- @@ -928,9 +958,10 @@
- }
-
- /*******************************************************************
- - create a unix date from a dos date
- + create a unix date (int GMT) from a dos date (which is actually in
- + localtime)
- ********************************************************************/
- -time_t make_unix_date(void *date_ptr,BOOL add_dst)
- +time_t make_unix_date(void *date_ptr)
- {
- uint32 dos_date=0;
- struct tm t;
- @@ -945,17 +976,18 @@
- t.tm_wday = 1;
- t.tm_yday = 1;
- t.tm_isdst = -1;
- -
- - ret = TimeLocal(&t,GMT_TO_LOCAL);
- +
- + /* mktime() also does the local to GMT time conversion for us. XXXXX
- + Do all unixes do this the same?? */
- + ret = mktime(&t);
-
- - if (add_dst) ret += DSTDiff(ret);
- return(ret);
- }
-
- /*******************************************************************
- - create a unix date from a dos date
- +like make_unix_date() but the words are reversed
- ********************************************************************/
- -time_t make_unix_date2(void *date_ptr,BOOL add_dst)
- +time_t make_unix_date2(void *date_ptr)
- {
- uint32 x,x2;
-
- @@ -963,9 +995,20 @@
- x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
- SIVAL(&x,0,x2);
-
- - return(make_unix_date((void *)&x,add_dst));
- + return(make_unix_date((void *)&x));
- }
-
- +/*******************************************************************
- + create a unix GMT date from a dos date in 32 bit "unix like" format
- +these generally arrive as localtimes, with corresponding DST
- +********************************************************************/
- +time_t make_unix_date3(void *date_ptr)
- +{
- + time_t t = IVAL(date_ptr,0);
- + if (!null_mtime(t))
- + t += LOCAL_TO_GMT*TimeDiff(t);
- + return(t);
- +}
-
- /*******************************************************************
- return a string representing an attribute for a file
- @@ -988,13 +1031,24 @@
-
-
- /*******************************************************************
- + case insensitive string compararison
- +********************************************************************/
- +int StrCaseCmp(char *s, char *t)
- +{
- + for (; tolower(*s) == tolower(*t); ++s, ++t)
- + if (!*s) return 0;
- +
- + return tolower(*s) - tolower(*t);
- +}
- +
- +/*******************************************************************
- compare 2 strings
- ********************************************************************/
- BOOL strequal(char *s1,char *s2)
- {
- if (!s1 || !s2) return(False);
-
- - return(strcasecmp(s1,s2)==0);
- + return(StrCaseCmp(s1,s2)==0);
- }
-
- /*******************************************************************
- @@ -1877,10 +1931,6 @@
- ****************************************************************************/
- int read_udp_socket(int fd,char *buf,int len)
- {
- - /* #define NORECVFROM */
- -#ifdef NORECVFROM
- - return(read_data(fd,buf,len));
- -#else
- int ret;
- struct sockaddr sock;
- int socklen;
- @@ -1901,7 +1951,6 @@
- DEBUG(3,("read %d bytes\n",ret));
-
- return(ret);
- -#endif
- }
-
- /****************************************************************************
- @@ -2539,7 +2588,7 @@
- /****************************************************************************
- send a single packet to a port on another machine
- ****************************************************************************/
- -BOOL send_packet(char *buf,int len,struct in_addr *ip,int port,int type)
- +BOOL send_one_packet(char *buf,int len,struct in_addr *ip,int port,int type)
- {
- BOOL ret;
- int out_fd;
- @@ -2620,7 +2669,7 @@
- if (strcmp(tok,s) == 0)
- return(True);
- } else {
- - if (strcasecmp(tok,s) == 0)
- + if (StrCaseCmp(tok,s) == 0)
- return(True);
- }
- }
- @@ -3261,18 +3310,6 @@
- return(ret);
- }
-
- -
- -/****************************************************************************
- -check if it's a null mtime
- -****************************************************************************/
- -static BOOL null_mtime(time_t mtime)
- -{
- - if (mtime == 0 || mtime == 0xFFFFFFFF)
- - return(True);
- - return(False);
- -}
- -
- -
- /****************************************************************************
- set the time on a file
- ****************************************************************************/
- @@ -3612,11 +3649,16 @@
- return(res);
- }
-
- -#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60 - (3.0*24*60*60 + 6.0*60*60))
- +#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
-
- /****************************************************************************
- interpret an 8 byte "filetime" structure to a time_t
- It's originally in "100ns units since jan 1st 1601"
- +
- +It appears to be kludge-GMT (at least for file listings). This means
- +its the GMT you get by taking a localtime and adding the
- +serverzone. This is NOT the same as GMT in some cases. This routine
- +converts this to real GMT.
- ****************************************************************************/
- time_t interpret_long_date(char *p)
- {
- @@ -3635,30 +3677,42 @@
- /* now adjust by 369 years to make the secs since 1970 */
- d -= TIME_FIXUP_CONSTANT;
-
- + if (d>=MAXINT)
- + return(0);
- +
- ret = (time_t)(d+0.5);
-
- + /* this takes us from kludge-GMT to real GMT */
- + ret += TimeDiff(ret) - serverzone;
- +
- return(ret);
- }
-
-
- /****************************************************************************
- put a 8 byte filetime from a time_t
- +This takes real GMT as input and converts to kludge-GMT
- ****************************************************************************/
- void put_long_date(char *p,time_t t)
- {
- uint32 tlow,thigh;
- - double d = (double) (t);
- + double d;
-
- if (t==0) {
- SIVAL(p,0,0); SIVAL(p,4,0);
- return;
- }
-
- + /* this converts GMT to kludge-GMT */
- + t -= TimeDiff(t) - serverzone;
- +
- + d = (double) (t);
- +
- d += TIME_FIXUP_CONSTANT;
-
- - d /= 1.0e-7;
- + d *= 1.0e7;
-
- - thigh = (uint32)(d / (4.0*(double)(1<<30)));
- + thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
- tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
-
- SIVAL(p,0,tlow);
- @@ -3800,7 +3854,7 @@
- #ifdef LINUX
- fstring s;
- sprintf(s,"/proc/%d",pid);
- - return(directory_exist(s));
- + return(directory_exist(s,NULL));
- #else
- {
- static BOOL tested=False;
- @@ -4137,8 +4191,8 @@
-
- int
- rename (zfrom, zto)
- - char const *zfrom;
- - char const *zto;
- + char *zfrom;
- + char *zto;
- {
- if (link (zfrom, zto) < 0)
- {
- @@ -4151,19 +4205,6 @@
- return unlink (zfrom);
- }
-
- -#endif
- -
- -#ifdef NOSTRCASECMP
- -/*******************************************************************
- - case insensitive string compararison
- -********************************************************************/
- -int strcasecmp(char *s, char *t)
- -{
- - for (; tolower(*s) == tolower(*t); ++s, ++t)
- - if (!*s) return 0;
- -
- - return tolower(*s) - tolower(*t);
- -}
- #endif
-
- #if WRAP_MEMCPY
- diff -u -r --new-file last-version/source/version.h samba-1.9.14p3/source/version.h
- --- last-version/source/version.h Sat Nov 4 23:21:27 1995
- +++ samba-1.9.14p3/source/version.h Tue Nov 7 23:00:33 1995
- @@ -1 +1 @@
- -#define VERSION "1.9.14p2"
- +#define VERSION "1.9.14p3"
-